React.js 카카오 로그인, 사용자 프로필 가져오기

개요

이번 포스트에서는 React에서 카카오의 REST API와 Javascript SDK를 이용해 카카오 로그인을 구현해보겠습니다.

동작 순서는 다음과 같습니다.

카카오 로그인 링크 클릭 -> 인가 코드 발급 -> Access Token 발급 -> 사용자 정보 획득

프로젝트 생성

React 프로젝트를 생성합니다.

npx create-react-app kakao-login

카카오 로그인에 사용될 Dependency 패키지들을 설치합니다.

npm install react-router-dom axios qs

프로젝트 확인

cd kakao-login

프로젝트 디렉토리로 이동해서 보면 아래와 같은 기본 생성된 파일 목록들을 볼 수 있습니다.

.
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   ├── reportWebVitals.js
│   └── setupTests.js
└── yarn.lock

React 프로젝트 기본 동작 확인

App.js 수정

App.js에 있는 내용을 지우고 아래와 같이 ‘hello’ 메시지만 출력되도록 합니다.

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      hello
    </div>
  );
}

export default App;

프로젝트 실행

npm start

프로젝트를 실행하고 브라우저에서 http://localhost:3000 으로 접속하면 아래와 같은 메인 페이지를 확인할 수 있습니다.

카카오 애플리케이션 생성

이제 카카오 로그인 기능을 React 프로젝트에 구현하기 위해 카카오 개발자 사이트에 만들어둔 Web Application 등록을 합니다.

개발자 사이트(https://developers.kakao.com/)에 접속해서 카카오 로그인을 위한 애플리케이션을 생성합니다.

로그인을 하고 “내 애플리케이션”을 클릭합니다.

‘애플리케이션 추가하기’ 버튼을 누릅니다.

앱 이름과 사업자명을 입력합니다.

애플리케이션 추가가 완료되면 요약 정보에 앱 키들을 확인 할 수 있습니다. 이 앱키들을 이용해서 Web, Android, iOS 등에서 카카오 로그인할 때 인증 절차를 받을 수 있습니다. 필자는 REST API를 이용해서 구현할 것이기 때문에 REST API키를 사용할 예정입니다.

그리고 플랫폼 등록 화면으로 가서 ‘Web 플랫폼 등록’을 해줍니다. 개발할 사이트 도메인을 추가해줍니다. 개발단계라 localhost 주소를 입력했습니다.

다음으로는 카카오 로그인 설정을 활성화 하고 Redirect URI를 추가합니다.

Redirect URI는 REST API키를 이용해서 카카오에 ‘인가 코드’를 받는 callback 주소입니다. 이후 소스를 보면 알겠지만, 카카오 로그인 버튼은

https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code

위와 같은 주소를 호출하고 카카오 서버에서 다시 redirect로 제가 입력해준 redirect URI로 이동하면서 인가 코드 값을 전달해주는 형태로 진행됩니다. 소스코드에서 다시 설명 될테니 우선 설정을 이어가겠습니다.

다음으로는 REST API를 사용하는 경우 필요한 Client Secret 코드 발급입니다. 보안 메뉴에서 코드 발급을 합니다.

인가 코드 발급 받기

이제 다시 프로젝트로 돌아와 인가 코드를 발급 받도록 구현해보겠습니다.

Auth.js 생성

./src/Auth.js를 생성하고 아래 코드를 입력합니다. 코드 내용은 Redirect 주소로 전달받은 code 값을 추출하여 보여주는 코드입니다.

import React from 'react';

const Auth = () => {
    const code = new URL(window.location.href).searchParams.get("code");
    return (
        <div>
            { code }
        </div>
    );
};

export default Auth;

App.js 수정

App.js를 다음과 같이 수정합니다.

import logo from "./logo.svg";
import "./App.css";
import Auth from "./Auth";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

function App() {
  const REST_API_KEY = "[본인 REST API KEY 값]";
  const REDIRECT_URI = "http://localhost:3000/oauth/kakao/callback";
  const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`;

  return (
    <Router>
    <div className="App">
      <Switch>
        <Route exact path="/">
          <h1><a href={KAKAO_AUTH_URL}>Kakao Login</a></h1>
        </Route>
        <Route path="/oauth/kakao/callback">
          <Auth />
        </Route>
      </Switch>
    </div>
    </Router>
  );
}

export default App;

코드를 보면 router를 이용해 kakao로 부터 인가 코드를 받기 위한 주소 링크를 메인 페이지에 띄우고 callback 주소로 “/oauth/kakao/callback” path를 추가하고 해당 path에 Auth page가 연결 되도록 했습니다.

페이지를 띄워보면 위와 같은 링크가 생성된 걸 볼 수 있습니다. 링크를 클릭하면 아래와 같이 카카오 계정 연동 페이지가 호출됩니다.

‘동의하고 계속하기’ 버튼을 누르면 필자가 만든 프로젝트의 callback 주소로 페이지가 다시 이동 됩니다. 이 때 인가 코드가 같이 전달되고 앞서 Auth.js에서 해당 코드를 출력하게 했으므로 아래와 같은 결과가 나옵니다.

Access Token 발급과 사용자 정보 가져오기

이제 실제 사용자 정보에 접근하기 위해 앞서 받은 인가 코드를 이용해 Access Token을 받고 사용자 정보를 획득해보겠습니다. 사용자 정보를 가져오기 위해서는 카카오 개발자 페이지의 동의항목에서 다음과 같이 개인 정보 사용 동의 설정을 해야합니다. 필자는 ‘닉네임’, ‘프로필 사진’ 등을 설정했습니다.

./public/index.html 수정

Kakao Javascript SDK를 사용하기 위해 index.html의 <head></head> 태그에 아래 코드를 추가합니다. REST API를 이용해서 Access Token을 발급 받는 것 까지는 카카오 Javascript SDK 없이 진행하는데 문제가 없으나 사용자 프로필을 가져오기 위한 kapi.kakao.com/v2/user/me URL 도메인에서 데이터를 획득하려면 CROS 정책 위반 에러가 발생합니다. Access Token 까지만 발급 받고 나머지 작업은 Backend에서 진행해도 되지만 본 포스트에서는 React 프로젝트 내에서 사용자 정보를 가져오기 위해 Kakao Javascript SDK를 사용했습니다.

<script src="https://developers.kakao.com/sdk/js/kakao.min.js"></script>

App.js 수정

App.js 파일을 다음과 같이 수정합니다. 이번엔 profile path를 추가했습니다.

import logo from "./logo.svg";
import "./App.css";
import Auth from "./Auth";
import Profile from "./Profile";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

function App() {
  const REST_API_KEY = "[본인 REST API KEY 값]";
  const REDIRECT_URI = "http://localhost:3000/oauth/kakao/callback";
  const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`;

  return (
    <Router>
      <div className="App">
        <Switch>
          <Route exact path="/">
            <h1>
              <a href={KAKAO_AUTH_URL}>Kakao Login</a>
            </h1>
          </Route>
          <Route path="/oauth/kakao/callback">
            <Auth />
          </Route>
          <Route path="/profile">
            <Profile />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

export default App;

Auth.js 수정

import React from "react";
import { useEffect } from "react";
import axios from "axios";
import qs from "qs";
import { useHistory } from "react-router-dom";

const Auth = () => {
  const REST_API_KEY = "[본인 REST API KEY 값]";
  const REDIRECT_URI = "http://localhost:3000/oauth/kakao/callback";
  const CLIENT_SECRET = "[본인 CLIENT SECRET 값]";

  // calllback으로 받은 인가코드
  const code = new URL(window.location.href).searchParams.get("code");

  const history = useHistory();

  const getToken = async () => {
    const payload = qs.stringify({
      grant_type: "authorization_code",
      client_id: REST_API_KEY,
      redirect_uri: REDIRECT_URI,
      code: code,
      client_secret: CLIENT_SECRET,
    });

    try {
      // access token 가져오기
      const res = await axios.post(
        "https://kauth.kakao.com/oauth/token",
        payload
      );
      
      // Kakao Javascript SDK 초기화
      window.Kakao.init(REST_API_KEY);
      // access token 설정
      window.Kakao.Auth.setAccessToken(res.data.access_token);
      history.replace("/profile");
    } catch (err) {
      console.log(err);
    }
  };

  useEffect(() => {
    getToken();
  }, []);

  return null;
};

export default Auth;

Auth.js 에서 인가 코드를 이용해서 Access Token을 가져옵니다. 가져온 Access Token을 Kakao 객체에 설정하기 위해 Kakao.Init()함수와 Kakao.Auth.setAccessToken() 함수를 호출합니다. 그리고 /profile 페이지로 이동합니다.

Profile.js 생성

Auth.js에서 Profile.js 페이지를 호출합니다. Profile.js 파일은 다음과 같습니다.

import React, { useEffect, useState } from "react";

const Profile = () => {
  const [user_id, setUserId] = useState();
  const [nickName, setNickName] = useState();
  const [profileImage, setProfileImage] = useState();

  const getProfile = async () => {
    try {
      // Kakao SDK API를 이용해 사용자 정보 획득
      let data = await window.Kakao.API.request({
        url: "/v2/user/me",
      });

      // 사용자 정보 변수에 저장
      setUserId(data.id);
      setNickName(data.properties.nickname);
      setProfileImage(data.properties.profile_image);
    } catch (err) {
      console.log(err);
    }
  };

  useEffect(() => {
    getProfile();
  }, []);
  return (
    <div>
      <h2>{user_id}</h2>
      <h2>{nickName}</h2>
      <img src={profileImage}></img>
    </div>
  );
};

export default Profile;

Kakao SDK의 Kaka.API.request를 호출합니다. /v2/user/me 경로를 호출하면 사용자 정보를 가져올 수 있습니다. Reqeust/Response의 상세 규격은 링크 페이지를 참고하기 바랍니다.

여기까지 완료하면 카카오 계정 연동을 거쳐 사용자 프로필을 얻는 게 가능합니다.

Github

작성했던 소스코드입니다.

https://github.com/warnus/react-kakao-login-example

Leave a Reply