data life

[팀프로젝트] REST-API 활용한 소셜 로그인 구현 - Kakao (feat. React) 본문

회고록

[팀프로젝트] REST-API 활용한 소셜 로그인 구현 - Kakao (feat. React)

주술회전목마 2023. 6. 20. 22:41

이번 프로젝트에서 로그인 및 회원가입 구현 담당을 맡게되면서 많이 헤메었던 소셜로그인 구현 방법을 정리해보는 시간을 가져보겠습니다. 

일단, 저희는 총 2가지 소셜 로그인 기능을 추가하였고

카카오, 네이버

그 중 카카오 로그인 구현을 먼저 시작해보겠습니다! 

 

사실 레퍼런스라면 많은 검색도 도움이 되었지만 그냥 카카오 공식문서를 차근차근 읽어보았던 게 가장 큰 도움이 되지 않았나..라는 생각입니다. 구현하기 전에 전체적인 흐름을 이해하기 위해서 꼭 한번 읽어보시길 바랍니다. 저 같은 경우 추가로 api 명세서도 수정해가면서 읽으니 금방 이해가 갔었던 것 같네요! 

 

참고로

- 카카오 개발자 센터에서 client_id, redirect_uri 등 기본적인것들은 먼저 설정하셔야 됩니다.
- REST API KEY를 사용하였습니다.
- 개발 환경 : React, Spring
- 프론트 위주로 설명할 예정입니다.

 

 

1. 인가 코드 받기

가장 먼저 해야할 일은 인가 코드를 받는 것입니다. 

인가 코드(Athorization Code)가 무엇인가 하면  Athor~(어서와~)라고 이해하시면 쉬울 듯 합니다.

즉, 사용자에게 인가(동의)받은 동의 항목 정보를 갖고 있으며, 이 인가 코드를 사용해서 토큰 받기를 요청할 수 있습니다.

 

아무래도 그림으로 설명해야 이해가 빠를 듯 싶네요.

동의 화면은 사용자와 해당 사이트가 처음 연결될 때에만 나타나고

사용자가 이미 동의를 완료한 경우에는 해당 사용자가 카카오 로그인 시에는 동의 화면이 나타나지 않고 즉시 인가 코드가 발급되는 구조입니다.

 

  • 카카오 계정 세션 ❌ ⇒ 카카오 로그인 화면 후, 동의화면 출력
  • 카카오 계정 세션 ⭕️ ⇒ 바로 동의화면 출력

 

예시는 다음과 같습니다. 

https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}
  • client_id : 앱 REST API 키 [내 애플리케이션] > [앱 키]에서 확인 가능
  • redirect_uri : 인가 코드를 전달받을 서비스 서버의 URI [내 애플리케이션] > [카카오 로그인] > [Redirect URI]에서 등록
    ❗️로컬에서 진행하므로 꼭 프론트 측 URL을 입력하시길 바랍니다
  • state : CSRF 공격으로 부터 카카오 로그인 요청을 보호하기 위함

아래는 백엔드에서 처리될 내용이라 간략하게 이해만 하고 넘어가면 될 듯 합니다.

 

 

코드 구현은 생각보다 간단합니다.

1. 카카오 소셜로그인 페이지 구현

// KakaoLoginPage.tsx
const REST_API_KEY = '발급받은 키 입력';
const REDIRECT_URI = 'redirect_uri 입력';
const link = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`;

  const handleKakaoLogin = () => {
    window.location.href = link;
  };

앞서 말한 [동의화면] > [동의하고 계속하기]를 선택하게 되면 주소창에 ?code={인가코드#$!@%!@%!@$} 로 넘어온 것을 확인할 수 있을 것!

 

2.  Redirect 페이지 구현

이제 저희가 할 일은 추출한 인가코드를 백엔드로 전달해주면 됩니다. 

인가코드 추출방법은 다음과 같습니다.

let code = new URL(window.location.href).searchParams.get('code');
//RedirectKakaopage.tsx
function RedirectKakaoPage() {
  useEffect(() => {
    const params = new URL(window.location.href).searchParams;
    const code = params.get('code');
    const grantType = 'authorization_code';
    const REST_API_KEY = process.env.REACT_APP_KAKAO_REST_API_KEY;
    const REDIRECT_URI = process.env.REACT_APP_KAKAO_REDIRECT_URI;
    const CLIENT_SECRET = process.env.REACT_APP_CLIENT_SECRET;
    const link = `https://kauth.kakao.com/oauth/token?grant_type=${grantType}&client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&code=${code}&client_secret=${CLIENT_SECRET}`;

    axios
      .post(
        link,
        {},
        {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
          },
        }
      )
      .then((res) => console.log(res))
      .catch((error) => {
        if (error.response) {
          //요청이 이루어졌으나 서버가 2xx 범위 이외로 응답한 경우
          console.log(error.response.data);
          console.log(error.response.status);
          console.log(error.response.headers);
        } else if (error.request) {
          //요청이 이루어졌으나 응답을 받지 못한 경우
          console.log(error.request);
        } else {
          //요청에 오류가 발생한 경우
          console.log(error.message);
        }
        console.log(error.config);
      });
  }, []);
  return <AddInfoPage />;
}

export default RedirectKakaoPage;

백엔드 쪽에서 저희가 넘겨준 인가코드를 이용해서 액세스토큰을 발급받아 유저정보를 조회하여 db에 저장한 뒤, jwt 토큰을 프론트로 전달해주면 로그인 과정은 끝입니다!

+ App.tsx 에서 Redirect_URI 경로 해당 컴포넌트 경로 설정

export default function App() {
  return (
    <Routes>
      <Route path="/" element={<MainPage />} />
      <Route path="/signin" element={<LoginPage />} />
      <Route path="/redirect-kakao" element={<RedirectKakaoPage />} />
    </Routes>
  );
}

이때, 저희는 Redirect URI에 대한 페이지를 정보 추가 페이지로 렌더링하여 추가 사용자 정보를 받을 수 있도록 하였습니다.

추가 정보들은 다음과 같습니다.

 

  • 프로필 url
  • 저희가 지정한 랜덤 닉네임 / 사용자가 수정한 닉네임
  • 주소 정보 (상세주소까진 받지 않음)

 

그래서 저희는 인가코드 + 위의 추가 정보들을 같이 담아서 백엔드 분들에게 전달해주면 됩니다! 

추가로 카카오도 OAuth 2.0 에 따라 액세스 토큰(Access token)과 리프레시 토큰(Refresh token) 두 가지로 발급합니다. 각 토큰의 역할 및 만료 시간은 다음과 같습니다.

콘솔창으로 데이터를 확인해보면 access_token refresh_token이 잘 받아진걸 확인할 수 있습니다!!

이제 받아진 데이터들과 함께 로그인 성공 처리를 해주면 끝!!

 

 

앞서한 과정을 모식도로 그린다면 다음과 같습니다! 지금 보니 정말 간단한데😂 왜이렇게 오래 걸리고 수많은 오류를 만났는 지 모르겠네요..

아무튼 저의 글이 많은 도움이 되길 바라며 다음엔 네이버 소셜로그인으로 돌아오겠습니다! 긴 글 읽어주셔서 감사합니다.