관리 메뉴

거니의 velog

(39) 리액트 소셜 로그인 2 본문

SpringBoot_React 풀스택 프로젝트

(39) 리액트 소셜 로그인 2

Unlimited00 2024. 3. 7. 17:42

3. 리액트에서 카카오 로그인

* API 서버는 하나의 서버로 여러 종류의 서비스나 앱에서 호출이 가능하기 때문에 소셜 로그인에 대한 실행은 반드시 프론트 애플리케이션에서 시작되어야 한다. 리액트에서는 여러 종류의 소셜 로그인 관련 라이브러리들이 존재하긴 하지만, 예제에서는 직접 구현을 해서 모든 과정을 이해해 본다(카카오 로그인에 관한 설명은 아래 문서를 참고).
https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com


(1) 인가 코드의 처리

* 가장 먼저 동의 화면과 로그인 화면 인가 코드를 처리해야 한다(아래 그림은 카카오 공식 문서의 화면이다).

* 인가 코드를 받기 위한 경로는 https://kauth.kakao.com/oauth/authorize 이고 다음과 같은 쿼리스트링이 필요하다.

* 프로젝트 내 api 폴더에 kakaoApi.js 파일을 추가한다.

* 카카오 로그인 관련 설정 정보 중에서 REST Key 값과 로그인후 이동할 Redirect Uri 정보를 이용해서 링크를 반환하도록 링크를 반환하도록 getKakaoLoginLink()를 추가한다.

//const rest_api_key = `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`; // REST키값
const redirect_uri = `http://localhost:3000/member/kakao`;

const auth_code_path = `https://kauth.kakao.com/oauth/authorize`;

export const getKakaoLoginLink = () => {
  const kakaoURL = `${auth_code_path}?client_id=${rest_api_key}&redirect_uri=${redirect_uri}&response_type=code`;
  return kakaoURL;
};

* components/member 폴더 내에 KakaoLoginComponent.js 를 추가한다.

import React from "react";
import { Link } from "react-router-dom";
import { getKakaoLoginLink } from "../../api/kakaoApi";

const KakaoLoginComponent = () => {
  const link = getKakaoLoginLink();

  return (
    <div className="flex flex-col">
      <div className="text-center text-blue-500">
        로그인 시에 자동 가입처리 됩니다
      </div>
      <div className="flex justify-center  w-full">
        <div className="text-3xl text-center m-6 text-white font-extrabold w-3/4 bg-yellow-500 shadow-sm rounded p-2">
          <Link to={link}>KAKAO LOGIN</Link>
        </div>
      </div>
    </div>
  );
};

export default KakaoLoginComponent;

* 기존의 LoginComponent에 KakaoLoginComponent를 import 해서 추가한다.

import React, { useState } from "react";
import useCustomLogin from "../../hooks/useCustomLogin";
import KakaoLoginComponent from "./KakaoLoginComponent";

const initState = {
  email: "",
  pw: "",
};

const LoginComponent = () => {
  (...)

  return (
    <div className="border-2 border-sky-200 mt-10 m-2 p-4">
      (...)
      <KakaoLoginComponent />
    </div>
  );
};

export default LoginComponent;

* 프로젝트를 실행하면 KAKAO LOGIN 버튼이 보이게 되고 클릭하면 카카오 로그인과 동의 화면을 볼 수 있다(동의 화면은 한 번만 보인다. 개인정보 보호창을 이용하는 것이 좋다).

* 로그인 후에는 Redirect Uri의 설정 경로로 이동하게 된다. 이때 쿼리스트링으로 인가 코드가 전달된다.


[인가 코드의 페이지 처리]

* 리액트 애플리케이션에서 Redirect Uri로 전달되는 경로가 없으므로 pages/member 폴더에 KakaoRedirectPage.js 를 추가한다.

import React from "react";
import { useSearchParams } from "react-router-dom";

const KakaoRedirectPage = () => {
  const [searchParams] = useSearchParams();
  const authCode = searchParams.get("code");

  return (
    <div>
      <div>Kakao Login Redirect</div>
      <div>{authCode}</div>
    </div>
  );
};

export default KakaoRedirectPage;

* 추가된 KakaoRedirectPage 에 대한 라우팅 설정을 추가한다.

import React, { Suspense, lazy } from "react";

const Loading = <div>Loading....</div>;
const Login = lazy(() => import("../pages/member/LoginPage"));
const Logout = lazy(() => import("../pages/member/LogoutPage"));
const KakaoRedirect = lazy(() => import("../pages/member/KakaoRedirectPage"));

const memberRouter = () => {
  return [
    {
      path: "login",
      element: (
        <Suspense fallback={Loading}>
          <Login />
        </Suspense>
      ),
    },
    {
      path: "logout",
      element: (
        <Suspense fallback={Loading}>
          <Logout />
        </Suspense>
      ),
    },
    {
      path: "kakao",
      element: (
        <Suspense fallback={Loading}>
          <KakaoRedirect />
        </Suspense>
      ),
    },
  ];
};

export default memberRouter;

* 브라우저에서 다시 로그인을 시도하면 아래와 같이 전달된 code 값이 출력되는 것을 확인할 수 있다.


(2) Access Token 받기

* 카카오 로그인 결과로 전달되는 인가 코드는 Access Token을 받기 위한 사전 작업이다(Access Token을 받기 위한 정보는 아래 주소를 참고).
https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-token

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

* Access Token을 받기 위해서는 https://kauth.kakao.com/oauth/token 을 호출해야 하고 전달해야 하는 값들은 REST Key 값, Redirect Uti, grant_type(고정값), 인가 코드가 필요하다.


[Access Token 호출]

* kakaoApi.js 에 getAccessToken() 함수를 추가한다. 인가 코드는 매번 변경되므로 파라미터로 처리한다.

import axios from "axios";

//const rest_api_key = `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`; // REST키값
const redirect_uri = `http://localhost:3000/member/kakao`;

const auth_code_path = `https://kauth.kakao.com/oauth/authorize`;
const access_token_url = `https://kauth.kakao.com/oauth/token`; // 추가

export const getKakaoLoginLink = () => {
  const kakaoURL = `${auth_code_path}?client_id=${rest_api_key}&redirect_uri=${redirect_uri}&response_type=code`;
  return kakaoURL;
};

export const getAccessToken = async (authCode) => {
  const header = {
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
  };
  const params = {
    grant_type: "authorization_code",
    client_id: rest_api_key,
    redirect_uri: redirect_uri,
    code: authCode,
  };
  const res = await axios.post(access_token_url, params, header);
  const accessToken = res.data.access_token;
  return accessToken;
};

* KakaoRedirectPage 에서는 useEffect() 를 사용해서 인가 코드가 변경되었을 때 getAccessToken() 을 호출하도록 변경한다.

import React, { useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import { getAccessToken } from "../../api/kakaoApi";

const KakaoRedirectPage = () => {
  const [searchParams] = useSearchParams();
  const authCode = searchParams.get("code");

  useEffect(() => {
    getAccessToken(authCode).then((data) => {
      console.log(data);
    });
  }, [authCode]);

  return (
    <div>
      <div>Kakao Login Redirect</div>
      <div>{authCode}</div>
    </div>
  );
};

export default KakaoRedirectPage;

* 브라우저에서 카카오 로그인을 수행하면 쿼리스트링으로 전달된 인가 코드를 이용해서 다시 카카오 서비스와 연동된 Access Token 값을 확인할 수 있다.


 

'SpringBoot_React 풀스택 프로젝트' 카테고리의 다른 글

(41) 리액트 소셜 로그인 4  (0) 2024.03.07
(40) 리액트 소셜 로그인 3  (0) 2024.03.07
(38) 리액트 소셜 로그인 1  (0) 2024.03.06
(37) 리덕스 툴킷 6  (1) 2024.03.06
(36) 리덕스 툴킷 5  (0) 2024.03.06