728x90
리액트로 카카오 아이디로 로그인 구현하기

 

❓상황

회원가입 대신, SNS 로그인 기능 구현해보고 싶어서 진행했다.

 

📖 SNS 로그인 구현

Kakao Developers setting

홈페이지 접속

 

Kakao Developers

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

developers.kakao.com

 

애플리케이션 등록

프로젝트 내에서 카카오 로그인을 구현하기 위해서, 사전작업으로 kakao developers에서 애플리케이션을 등록해야한다.

로그인 후, 내 애플리케이션 클릭

 

애플리케이션 추가 클릭

 

사진, 이름, 사업자명을 입력하고 저장버튼 클릭

 

생성된 애플리케이션 클릭

 

앱 키가 노출 될 경우에는, 새로 애플리케이션을 추가하지 않고 재발급 버튼을 눌러 재발급을 받으면 된다.

앱 키는 중요한 정보이기때문에, 노출되어서는 안된다.

 

플랫폼 설정하기

Android, IOS, Web 플랫폼을 등록할 수 있는 화면이다.

나는 Web 애플리케이션으로 카카오 로그인을 구현할 것이니, Web 플랫폼을 등록하면 된다.

Web 플랫폼 등록버튼 클릭

 

Web 플랫폼을 등록할 사이트 도메인을 입력한다.나는 테스트용으로 사용하기 때문에, localhost:3000을 입력해주었다.

사이트 도메인 입력 후, 저장버튼 클릭

 

등록된 나의 Web 도메인

 

카카오 로그인 활성화

카카오 로그인을 활성화해야, 카카오 로그인 구현이 가능하다.

OFF 토글버튼을 클릭

 

활성화버튼 클릭

 

다음으로는 Redirect URL을 설정해 주어야한다.

 

나중에 내가 구현할 '카카오 계정으로 로그인하기'을 클릭할 경우 카카오 서비스가 호출이 되고, 카카오 서비스가 로그인된 카카오 계정의 정보를 나에게 주면, 로그인된 카카오 계정의 정보를 내가 활용할 수 있다.

 

사실 나는 팝업으로 로그인을 구현하기때문에 필요없는 작업이다.

만일 리다이렉트로 로그인을 구현하려면, 해당 작업은 필수이다.

 

Redirect URL 등록버튼 클릭

카카오 서비스를 호출하면, 카카오에서 전달해준 정보를 받을 URL을 설정하는 것이다. 

카카오 정보를 받을 URL을 입력하고, 저장버튼을 클릭

 

등록된 URL

 

카카오로 부터 받을 정보 설정

동의항목으로 이동하여, 카카오 로그인으로 서비스를 시작할 때 동의받는 항목을 설정해준다.

 

개인정보와 접근권한을 설정할 수 있다.

카카오 동의항목

닉네임, 사진, 이메일 동의항목을 설정하려고 한다.

 

오른쪽에  '설정'버튼 클릭하면 설정을 진행할 수 있다.

오른쪽에 있는 설정버튼 클릭

 

필수 동의 체크, 동의 목적 입력 후 저장버튼 클릭

 

카카오 이메일 정보를 얻으려면 검수가 필요하기때문에, 선택 동의를 체크한다.

 

이메일 정보가 필요한 경우가 발생시 계속 동의 요청을 할 수 있도록 '카카오 계정으로 정보 수집 후 제공'을 체크한다.

 

동의목적과 저장버튼을 클릭한다.

선택 동의, 간헐적인 정보수집 요청, 동의 목적 체크 및 작성 후, 저장버튼 클릭

 

카카오 Javascript SDK 및 앱 키 등록

카카오 Javascript SDK 등록

카카오 로그인을 구현하기 위해서는 카카오에서 제공하는 Javascript SDK를 내가 만든 프로젝트에 추가해야한다.

 

 

Kakao Developers

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

developers.kakao.com

 

위의 링크를 접속하면, javascript SDK를 볼 수 있는데 SDK를 내가 만든 프로젝트에 추가해주면 된다.

# html > head
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>

 

카카오 앱 키 등록

카카오 애플리케이션 추가할때, 봤던 javascript 앱 키를 프로젝트에 등록한다.

 

나는 리액트를 사용하고 있어서, 리액트로 코드를 구현했다.

  # app.js / react
  const initKakao = () => {
    const jsKey = "3c5fd0d61672a00438664be501823461";
    const Kakao = window.Kakao;
    if (Kakao && !Kakao.isInitialized()) {
      Kakao.init(jsKey);
      console.log(Kakao.isInitialized());
    }
  };

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

 

Kakao.init('자바스크립트 앱 키')는 Javascript SDK를 앱 키로 초기화한다.

 

Kakao.isInitailized()는 초기화가 잘 되었는지 boolean 데이터를 반환해준다.

 

의도했던대로, ture가 잘 나온다.

 

로그인 구현

로그인 버튼 구현

공식 문서를 참고하여, 로그인 버튼을 구현했다.

 

Kakao Developers

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

developers.kakao.com

<div className="App">
      <h2>카카오 로그인 구현</h2>
      <button onClick={kakaoLogin}>
        <img
          src="//k.kakaocdn.net/14/dn/btroDszwNrM/I6efHub1SN5KCJqLm1Ovx1/o.jpg"
          width="222"
          alt="카카오 로그인 버튼"
        />
      </button>
</div>

 

로그인 코드 구현

공식문서 로그인 코드 양식을 참고하여 구현했다.

 

Kakao Developers

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

developers.kakao.com

const kakaoLogin = () => {
    Kakao.Auth.login({
      success() {
        Kakao.API.request({
          url: "/v2/user/me",
          success(res) {
            alert(JSON.stringify(res));
            const kakaoAccount = res.kakao_account;
            console.log(kakaoAccount);
          },
          fail(error) {
            console.log(error);
          },
        });
      },
      fail(error) {
        console.log(error);
      },
    });
};

 

로그인 제대로 동작하는지 확인

이제 버튼을 누르면, 카카오 로그인이 진행이 된다.

 

카카오 로그인시 사용자에게 '우리 서비스를 이용하려면 어떤 어떤 정보가 필요해요' 라고 말하듯이 팝업창으로 정보를 요청한다.

 

동의항목은, 사전에 설정한 닉네임, 프로필 사진, 이메일계정이 나와있다.

동의항목이 나열되어 있다.

 

카카오 사용자 정보 가져오기

닉네임, 이메일, 프로필 사진 가져오기

리액트의 useState를 이용하여, 객체 데이터로 얻었다.

const [user, setUser] = useState(null);

const kakaoLogin = () => {
    Kakao.Auth.login({
      success() {
        Kakao.API.request({
          url: "/v2/user/me",
          async success(res) {
            console.log(res);
            const kakaoAccount = res.kakao_account;
            setUser({
              email: kakaoAccount.email,
              profileImg: kakaoAccount.profile.profile_image_url,
              nickname: kakaoAccount.profile.nickname,
            });
          },
          fail(error) {
            console.log(error);
          },
        });
      },
      fail(error) {
        console.log(error);
      },
    });
  };

 

데이터를 브라우저에 출력하기

정상적으로 사용자 정보 데이터를 잘 가져왔는지 화면에 출력하려고 한다.

 

이때, 카카오 로그인을 하지않아 user 데이터가 null일 경우 화면에 표시되는 것이 없게 만들었다.

카카오 로그인을 하여, user 데이터가 객체데이터로 바뀌었을때, 화면에 표시하도록 코드를 작성했다.

return (
	{user && (
        <div>
          <h2>카카오 로그인 성공!</h2>
          <h3>카카오 프로필 사진</h3>
          <img src={user.profileImg} alt="" />
          <h3>카카오 닉네임</h3>
          <h4>{user.nickname}</h4>
          <h3>카카오 이메일</h3>
          <h4>{user.email}</h4>
        </div>
	)}
)

 

아래는 화면에 표시되는 과정이다.

닉네임, 이메일, 프로필 사진까지 정상적으로 잘 출력되었다.

 

로그인 상태 확인

카카오 로그인

카카오 로그인을 하면, 로그인했다고 변수를 저장하자.

const [isLogin, setIsLogin] = useState(false);

  const kakaoLogin = async () => {
    await Kakao.Auth.login({
      success(res) {
        console.log(res);
        Kakao.Auth.setAccessToken(res.access_token);
        console.log("카카오 로그인 성공");

        Kakao.API.request({
          url: "/v2/user/me",
          success(res) {
            console.log("카카오 인가 요청 성공");
            const kakaoAccount = res.kakao_account;
            setIsLogin(true);
          },
          fail(error) {
            console.log(error);
          },
        });
      },
      fail(error) {
        console.log(error);
      },
    });
  };

 

카카오 로그인 상태 확인

카카오 로그인을 하면, 정상적으로 로그인했다는 정보를 얻을 수 있다.

그 정보는 바로, 토큰이다.

 

토큰은 Kakao.Auth.getAccessToken()을 통해 값을 얻을 수 있다.

  useEffect(() => {
    initKakao();
    Kakao.Auth.getAccessToken() ? setIsLogin(true) : setIsLogin(false);
  }, []);

 

async await로 카카오 초기화까지 기다리기

해당 코드를 실행하게 되면, 오류가 발생한다.

그 이유는, 카카오가 초기화되기 전에 카카오 메소드를 실행시켰기 때문이다.

 

따라서, 카카오가 초기화 되고 나서 카카오 메소드를 실행시키기 위해, 비동기함수 async await를 이용해야한다.

initKakao()가 내가 정의한 카카오 초기화 함수이므로, 이 함수가 완료될때까지 기다리도록 비동기함수를 이용하자

  const initKakao = async () => {
    const jsKey = "3c5fd0d61672a00438664be501823461";
    if (Kakao && !Kakao.isInitialized()) {
      await Kakao.init(jsKey);
      console.log(`kakao 초기화 ${Kakao.isInitialized()}`);
    }
  };

 

localStorage에 카카오 사용자 정보 저장

로그인 성공시 localStorage에 저장하기

const kakaoLogin = async () => {
    await Kakao.Auth.login({
      success(res) {
        console.log(res);
        Kakao.Auth.setAccessToken(res.access_token);
        console.log("카카오 로그인 성공");

        Kakao.API.request({
          url: "/v2/user/me",
          success(res) {
            console.log("카카오 인가 요청 성공");
            const kakaoAccount = res.kakao_account;
            localStorage.setItem("email", kakaoAccount.email);
            localStorage.setItem(
              "profileImg",
              kakaoAccount.profile.profile_image_url
            );
            localStorage.setItem("nickname", kakaoAccount.profile.nickname);
            setIsLogin(true);
          },
          fail(error) {
            console.log(error);
          },
        });
      },
      fail(error) {
        console.log(error);
      },
    });
  };

 

로그아웃시 localStorage 데이터 삭제하기

localStorage는 수동으로 삭제하지 않는 이상, 브라우저를 닫거나 페이지를 이동해도 데이터가 남아있다.

그래서 로그아웃하면, 사용자 데이터를 삭제하도록 코드를 구현했다.

  const kakaoLogout = () => {
    Kakao.Auth.logout((res) => {
      console.log(Kakao.Auth.getAccessToken());
      console.log(res);
      localStorage.removeItem("email");
      localStorage.removeItem("profileImg");
      localStorage.removeItem("nickname");
      setUser(null);
    });
  };

 

⭐ 카카오 로그인 확인하여 데이터 화면에 표시

현재까지의 내가 개발한 상황은 새로고침하면, user데이터가 날아가버려서 카카오 로그인을 했음에도 user데이터가 없어 화면에 출력할 수가 없다.

 

카카오로부터 얻은 데이터를 저장하고, 저장된 데이터를 화면에 표시하기위해 로그인 상태를 확인하고, localStorage에 데이터를 저장하는 코드를 구현했다.

 

이제는 저장된 데이터를 꺼내어 화면에 표시하면 된다.

  useEffect(() => {
    console.log(isLogin);
    if (isLogin) {
      setUser({
        email: localStorage.getItem("email"),
        profileImg: localStorage.getItem("profileImg"),
        nickname: localStorage.getItem("nickname"),
      });
    }
  }, [isLogin]);

 

최종

전체 코드

import { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [user, setUser] = useState(null);
  const [isLogin, setIsLogin] = useState(false);
  const { Kakao } = window;
  const initKakao = async () => {
    const jsKey = "3c5fd0d61672a00438664be501823461";
    if (Kakao && !Kakao.isInitialized()) {
      await Kakao.init(jsKey);
      console.log(`kakao 초기화 ${Kakao.isInitialized()}`);
    }
  };
  const kakaoLogin = async () => {
    await Kakao.Auth.login({
      success(res) {
        console.log(res);
        Kakao.Auth.setAccessToken(res.access_token);
        console.log("카카오 로그인 성공");

        Kakao.API.request({
          url: "/v2/user/me",
          success(res) {
            console.log("카카오 인가 요청 성공");
            setIsLogin(true);
            const kakaoAccount = res.kakao_account;
            localStorage.setItem("email", kakaoAccount.email);
            localStorage.setItem(
              "profileImg",
              kakaoAccount.profile.profile_image_url
            );
            localStorage.setItem("nickname", kakaoAccount.profile.nickname);
          },
          fail(error) {
            console.log(error);
          },
        });
      },
      fail(error) {
        console.log(error);
      },
    });
  };

  const kakaoLogout = () => {
    Kakao.Auth.logout((res) => {
      console.log(Kakao.Auth.getAccessToken());
      console.log(res);
      localStorage.removeItem("email");
      localStorage.removeItem("profileImg");
      localStorage.removeItem("nickname");
      setUser(null);
    });
  };

  useEffect(() => {
    initKakao();
    Kakao.Auth.getAccessToken() ? setIsLogin(true) : setIsLogin(false);
  }, []);

  useEffect(() => {
    console.log(isLogin);
    if (isLogin) {
      setUser({
        email: localStorage.getItem("email"),
        profileImg: localStorage.getItem("profileImg"),
        nickname: localStorage.getItem("nickname"),
      });
    }
  }, [isLogin]);

  return (
    <div className="App">
      <h2>카카오 로그인 구현</h2>
      {user ? (
        <div>
          <button onClick={kakaoLogout}>로그아웃</button>
          <h2>카카오 로그인 성공!</h2>
          <h3>카카오 프로필 사진</h3>
          <img src={user.profileImg} alt="" />
          <h3>카카오 닉네임</h3>
          <h4>{user.nickname}</h4>
          <h3>카카오 이메일</h3>
          <h4>{user.email}</h4>
        </div>
      ) : (
        <button onClick={kakaoLogin}>
          <img
            src="//k.kakaocdn.net/14/dn/btroDszwNrM/I6efHub1SN5KCJqLm1Ovx1/o.jpg"
            width="222"
            alt="카카오 로그인 버튼"
          />
        </button>
      )}
    </div>
  );
}

export default App;

 

참고사항

로그인 유지?

카카오 로그인을 하면 카카오 사용자 정보를 user 변수에 담았다.

그리고 user에 담은 사용자 정보를 화면에 출력했다.

 

로그인 상태에서 새로고침을 하면 카카오 사용자 정보를 담은 user 변수가 초기화가 되서 화면에 사용자 정보가 출력이 안되는 것이었다.

 

처음에는 로그인이 해제되는 줄 알고, 인터넷으로 로그인 유지하는 방법을 찾아보게되었다.

 

원래 새로고침하면 초기화되는 것을 뒤늦게 하루 지나고 알아차리고 나자, 괜한 헛고생을 했다는 생각을 했다.

 

데이터 저장?

현재는 임시방편으로 localStorage에 사용자 정보를 저장했는데, Node.js를 공부하게 되면 서버쪽 DB에 데이터를 저장해서 사용해봐야겠다는 생각을 하게되었다.

 

TMI

카카오 사전세팅 1일, 카카오 로그인 유지 찾아보기 1일, 개발 1일. 카카오 로그인을 구현해보는데 약 3일 걸렸다....

카카오를 끝냈으니 다음에는 네이버 로그인도 구현해보려고하는데, 후딱 끝내야지

복사했습니다!