6일간 카톡 소셜로그인만 했다는 시간이 아까워서 정말 자세히 기록해 놓고 싶어서 작성한다 🧑🏻💻
간단 요약
- REST-API를 활용한 카카오톡 로그인 방법 사용
- 프론트엔드와 - 백엔드 함께 작업
- 프론트엔드 : 카카오로부터 인가코드를 받고 인가코드를 백엔드에 넘겨주는 역할 (+ 마지막 리다이렉팅까지)
- 백엔드 : 프론트로부터 인가 코드를 넘겨받고 카카오로부터 토큰을 발급받는다. 그리고 해당 토큰에 담긴 유저 정보를 활용해 프로젝트 전용 토큰으로 새롭게 발급 후 프론트에게 돌려준다.
백엔드에서 카카오 토큰을 프로젝트 전용 토큰으로 새롭게 발급하는 이유는
카카오 토큰을 그대로 클라이언트에게 직접 넘겨주고 사용시키다가 해킹 당하면 고소 당하는 거임
1. 인가코드 받기
카톡 소셜로그인을 위해서는 우선 여기 사이트에 들어가서
내 애플리케이션 - > 애플리케이션 추가해 준다.
https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
그리고 아래와 같이 Request URL을 요청하면 인가코드를 받을 수 있다.
URL 구조를 안다면 저 코드를 한 줄로만 작성할 수 있다.
사진에서 보는것과 같이 Protocol 뒤에 들어가는게 Host명이기 때문에 뒤에 붙혀서 한줄로 나열하면 된다.
"https://kauth.kakao.com/oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code"
이렇게 작성하면 인가코드를 받을 수 있을줄 알았겠지만 아니다. (단호)
적혀져 있는데로 client_id와 redirect_url 부분을 채워주어야 한다.
2. cliend_id
이제 추가한 애플리케이션 을 누르면 REST API 키가 나오는데 우리는 이걸 cliend_id에 사용한다.
3. Redirect URI
Redirect URI는 카카오 로그인 메뉴에 들어가서 추가를 해준다. 이때 경로 설정은 백엔드와 협의해서 맞춘다.
우린 백엔드분이 하자는 경로로 따라갔다. (api/auth/kakao/callback)
우리는 처음에 백엔드서버주소 http://3.35~~~/api/auth/kakao/callback주소로 따라 갔는데 인가코드 받는게 되어서 어? 이것도 되나보다 했는데 나중에 인가코드 우리가 백에 보내고 백에서 우리한테 토큰 보낼때 통신이 백에서 백으로 돌아간다.
결국 이 URL은 http://localhost:3000/api/auth/kakao/callback으로 수정함
그냥 프론트에서 접근할 수 있는 Host(localhost:3000)으로 해라 ^^
4. 플랫폼 추가
우리 프로젝트는 Web에서 사용할 것이기 때문에 Web 플랫폼에 사이트 도메인을 추가하는데 아직 배포전이라서 localhost:3000을 적었고, 배포하면 배포된 주소를 추가하면 된다.
여기까지의 과정은 백엔드나 프론트나 아무나 해도 상관없는데, 반드시 한 사람의 REST_API 혹은 REDIRECT_URI를 따라가야 한다.
이렇게 모은 것들을 한번에 편하게 관리하기 위해 컴포넌트를 새로 생성했다.
> OAuth.jsx
// OAuth.js 라는 컴포넌트를 따로 생성하여 관리하였음
const CLIENT_ID = "11111111111111111111111111111111";
const REDIRECT_URI = "http://localhost:3000/oauth/callback/kakao";
export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;
이건 .gitignore에 넣어 관리하는걸 추천한다.
> Login.jsx
import { KAKAO_AUTH_URL } from '../components/login/Oauth';
<KaKaoBtn onClick={handleLogin}>
<img style={{ transform: 'scale(0.3)' }} src="/img/kakao1.png"></img>
<span>카카오계정 로그인</span>
</KaKaoBtn>
이런 다음 카카오계정 로그인 버튼을 눌렀을때 카카오톡 로그인 화면으로 이동이 되고, 동의하기 화면이 나온다.
※ 참고 : 혹시나 이메일을 필수로 하고 싶다면 개인개발자 비즈앱 설정하면 이메일 필수동의가 가능하다.
이제 동의하고 계속하기! 를 누르면 나오는데 Redirect_URI화면이다.
이 화면에는 보이지 않는 모든 것이 이루어지는데
주소창을 보면 Redirect_URI 뒤에 파라미터로 ?code=~~~~~~
인가 코드가 넘어온 것을 확인할 수 있다.
프론트에서 받는 인가 코드가 바로 이것이다.
이제 이 인가 코드를 추출할면 좋은 명령어가
let 변수명 = new URL(window.location.href).searchParams.get('code')
이것이다.
5. 인가 코드 백엔드에 넘기고 토큰 받기
이제 우리는 이 빈 화면이 Redirect_URI 주소창으로 뜬다는걸 알았으니 이 URI에 해당하는 컴포넌트를 작성해주었고, 라우터를 걸었다.
> Router.js
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Login from '../pages/Login';
import Kakao from '../components/login/kakao';
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/api/auth/kakao/callback" element={<Kakao />}></Route>
</Routes>
</BrowserRouter>
);
};
export default Router;
사실 다른 블로그들을 보면 여기서 또 분리해서 사용하던데 나는 그렇게하면 오류 찾는게 힘들어서 kakao.jsx 파일을 만들어서 다 집어 넣었다.
여기서부터 백엔드랑 axios통신이 안됬다. ^^
그리고 무조건 여기서는 백엔드 주소를 넣어라 안그러면 나랑 나랑 통신하는 바보 놀이 한다 ㅎㅎ
처음에는 GET 메소드 하나로 다 처리하려고 했는데 받아와 지지 않아서 한번 토큰 보내고 받는걸 get이랑 post 메소드로 나눠서 해보자고 해서 되었다.
1. get - 인가코드 보내주면서 카톡 토큰 받음
2. post - 받은 카톡 토큰을 다시 백에 보내주면서 가공된 프로젝트의 토큰을 받아둔다.
(여기서 백엔드가 악시오스를 통해서 카카오톡이랑 통신해서 카톡전용 토큰을 받는다.)
여기서 또 중간에 백에서 아래와 같이 오류 뜨는데 client_secret이 활성화된 상태에서 client_secret을 파라메터로 안넘긴 경우에 해다한다. 아래 글 슬며시 백에 들이밀어라
https://devtalk.kakao.com/t/koe010-bad-client-credentials/115388
KOE010 (Bad client credentials) 에러가 발생할 때
{“error”:“invalid_client”¸ “error_description”:'Bad client credentials'¸ “error_code”:'KOE010'} KOE010 (Bad client credentials) 에러가 발생할 때 ◾️ 대부분 client_secret이 활성화된 상태에서 client_secret을 파라메
devtalk.kakao.com
{“error”:“invalid_client”¸
“error_description”:'Bad client credentials'¸
“error_code”:'KOE010'}
그리고 아래 코드를 보면 알다시피 사실 우리는 토큰이 필요 없었다..그치만 가공된 토큰이 필요해서 일단 받았는데 필요하면 넣을듯
여기서 이제 홈으로 넘어가는 과정에서 조금 로딩이 걸려서 spinner도 넣었다.
마지막으로 홈페이지에 넘어간 다음에 이전페이지로 넘어가서 인가코드를 탈취하는 것을 방지하기 위하여 window.location.replace('/home')으로 메인화면에 보내줌으로 소셜 로그인을 마무리 하게 되었다.
진짜 악시오스 두번 중첩해서 첨써본다 이것 덕분에
> kakao.jsx
// 리다이렉트될 화면
import React from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import { useCookies } from 'react-cookie';
import { useEffect } from 'react';
import Spinner from '../../elements/Spinner';
//리다이렉트 화면
const Kakao = () => {
const navigator = useNavigate();
const [cookies, setCookie] = useCookies(['nickname']);
// 인가코드
let code = new URL(window.location.href).searchParams.get('code');
const Token = async () => {
try {
const res = await axios.get(
`http://3.백주소 넣어/api/auth/kakao/callback?code=${code}`
);
const kakaoToken = res.data.accessToken;
console.log(kakaoToken);
localStorage.setItem('kakaotoken', kakaoToken);
if (res.status === 200) {
const res2 = await axios.post(
`http://3백 주소 넣어/api/auth/kakao/callback?code=${code}`,
{
kakaoToken, //카카오 토큰
},
{
headers: {
Authorization: `Bearer ${kakaoToken}`,
},
}
);
console.log(res2);
const nickname = res2.data.nickname;
// console.log(nickname);
setCookie('nickname', nickname, {
path: '/',
secure: true,
sameSite: 'none',
});
// console.log(cookies);
if (res2.status == 200) {
window.location.replace('/home');
}
} else {
alert('카카오톡 요청 실패');
navigator('/');
}
} catch (error) {
console.log(error);
alert('로그인 실패');
navigator('/');
}
};
useEffect(() => {
Token();
}, [Token()]);
return <Spinner />;
};
export default Kakao;
'React' 카테고리의 다른 글
배포 환경 설정 (.env) (0) | 2022.11.24 |
---|