먼저, 이전에 React + Firebase로 구글 로그인을 구현했었다.
아무래도 우리나라 대다수 국민이 카카오톡을 많이 사용하는 만큼, 카카오 로그인도 있으면 매우 편리할 것이라고 생각하기에 카카오 로그인 기능도 구현해보려고 한다.
먼저 Kakao Developers에 방문하여 Full SDK를 복사합니다.
그 다음으로 복사한 SDK 코드를 index.html의 <title>
아래에 추가합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
<-- 여기 -->
<script src="https://t1.kakaocdn.net/kakao_js_sdk/2.2.0/kakao.min.js" integrity="sha384-x+WG2i7pOR+oWb6O5GV5f1KN2Ko6N7PTGPS7UlasYWNxZMKQA63Cj/B2lbUmUfuC" crossorigin="anonymous"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
아래의 플랫폼 메뉴에서 플랫폼 설정하기 버튼을 눌러서 사용하고자 하는 플랫폼을 등록합니다. 저는 웹앱이므로 Web을 등록했습니다.
상단 메뉴의 내 애플리케이션을 눌러봅시다.
기존에 생성한 프로젝트가 있다면 해당 프로젝트를 클릭하고 JavaScript 키를 복사해줍니다.
프로젝트가 없다면 새로 생성해서 동일한 과정을 수행합시다.
복사한 키를 가지고 임의의 js파일에 다음과 같은 코드를 추가합니다.
저는 kakaologin.js
라는 파일을 생성하고 여기에 추가했습니다.
const kakaologin = () => {
if (!window.Kakao.isInitialized()) {
window.Kakao.init('cfc1aaa067d4f612945273d5dac8a9c8');
}
}
export default kakaologin;
예시에서는 JavaScript 키를 사용했는데, 앞으로의 구현은 REST API 키를 사용했다.
[내 애플리케이션] > [제품설정] > [카카오 로그인]
내 애플리케이션에서 프로젝트에 들어갑니다.
왼쪽 메뉴에 카카오 로그인 항목을 클릭합니다.
처음에 활성화 설정의 상태는 OFF입니다. ON으로 변경해줍시다.
그 다음으로 Redirect URI를 설정해줘야 합니다.
다음으로는 동의항목을 설정해줍니다.
[내 애플리케이션] > [제품설정] > [카카오 로그인] > [동의항목]
아래의 정보들을 자신의 원하는대로 필요에 맞게 설정해주면 됩니다.
저는 테스트용으로 다음과 같이 설정했습니다.
백엔드 코드를 작성하기 위해서 Cloud Functions을 사용했는데,
firebase deploy --only functions
위 명령어 사용시 Blaze 요금제로 바꿔야 수행가능하다고 한다...
다른 사람들은 문제없이 하던데, 최신 글이 아니라서 그새 정책이 바뀌었나보다.
해당 오류
Error: Your project logintest-7c52f must be on the Blaze (pay-as-you-go) plan to complete this command. Required API cloudbuild.googleapis.com can't be enabled until the upgrade is complete. To upgrade, visit the following URL:
아무래도 다른 방법을 찾아봐야겠다.
React로 구현한 코드는 거의 없다시피해서 계속해서 관련 글을 찾다가 Vue로 구현한 블로그를 찾았다. 똑같이 Cloud Functions을 사용하는데, 이전에 발생했던 요금제 변경을 우회할 수 있는 방법이 있었다.
자세한 에러 발생 원인을 찾아보니 firebase에서 Node.js 10 이상 부터는 Blaze 요금제를 사용해야 한다는 것이었다. Node.js의 버전을 내리면 임시로 해결이 가능했다.
해결법은 여기서 찾아볼 수 있다.
그런데 배포 중 계속해서 에러가 발생해서 일단은 너무 삽질을 많이 한 관계로 포기했다. 😭(에러를 캡처해뒀어야 하는데 기억이 안난다..)
솔직히 다른 환경(Flutter, Swift, Kotlin 등)에서 구현한 코드는 많은데 React는 자료가 너무 없어서 아무리 해도 안될 것 같아 구현 자체를 포기했었다.
근데 또 이놈의 성격이 끝내지를 못하면 머릿속에 계속 생각이 나서, 알고리즘 문제를 풀 때도 "아!!! 어떻게 해결될 것 같은데, 조금만 더 해볼까? 🧐" 하는 생각이 떠나질 않았다.
해결 방법은 2가지 이다.
이 중 나는 일단은 서버 구축이라면 거부감이 들어, OpenID Connect를 사용해서 구현했다. 추후 필요에 따라 Node.js 서버를 사용해서 구현을 해보겠다.
일단 들어가기 전, 위에서 JavaScript 키를 사용했는데 이제부터 구현할 코드는 REST API 키를 사용했다.
본 포스팅은 모든 코드에 대해 설명하지 않습니다. 전체 코드가 필요하다면 이곳에서 확인해주세요.
+) 코드가 좀 지저분하고 세세한 디테일까지는 신경쓰지 못했습니다. 작동 여부만 참고하는 것을 추천드립니다.
일단, 거창한 CSS 같은 건 필요없이 기능 동작 여부만 확인하면 되므로 아주 간단하게 작성했다.
첫 페이지(localhost:3000
)에서 Kakao 로그인이라는 버튼을 하나 만들고, 해당 버튼을 클릭하면 간편 로그인을 할 수 있다.
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
├── App.js
├── Kakao.js
├── KakaoLogin.js
├── config.js
└── index.js
[공지] 카카오 로그인 OpenID Connect 지원을 살펴보면 카카오 로그인이 이제 OpenID Connect를 지원한다고 한다.
먼저, 카카오 Developer에 들어가서 왼쪽의 카카오 로그인 항목을 선택하자.
항목에 OpenID Connect 활성화 설정이 있다. 처음 상태는 OFF이다.
이를 ON으로 바꿔주자.
React + Firebase로 구글 로그인 구현하기에서 했던 작업과 똑같다.
만약, 똑같은 프로젝트를 사용하고 있다면 그대로 사용하면 된다.
// ✅ /src/config.js
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "[본인 프로젝트의 값]",
authDomain: "[본인 프로젝트의 값]",
projectId: "[본인 프로젝트의 값]",
storageBucket: "[본인 프로젝트의 값]",
messagingSenderId: "[본인 프로젝트의 값]",
appId: "[본인 프로젝트의 값]"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
export { app, auth };
추후에 필요한 콜백 페이지부터 설정해야 한다.
위의 프로젝트 구조에서 KakaoLogin.js
는 로그인 버튼을 나타내는 컴포넌트이고, 인가 코드 받기를 요청한다.
Kakao.js
는 Redirect URI
를 의미하는 콜백 페이지이고, KakaoLogin
에서 받은 인가 코드를 바탕으로 ID 토큰과 Access Token을 요청하는 함수들이 모여있다.
위 정보를 바탕으로 react-router-dom
을 사용해서 index.js
에 Route
를 설정해야 한다.
// ✅ /src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Route, Routes, BrowserRouter as Router } from "react-router-dom";
import Kakao from "./Kakao";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Router>
<Routes>
<Route path="/" element={<App />} />
<Route path="/callback/kakaotalk" element={<Kakao />} />
</Routes>
</Router>
);
/callback/kakaotalk
은 내가 설정한 Redirect URI
이다.
✅ 본인이 설정한 값에 맞게 변경해줘야 한다.
카카오 로그인 함수인 Kakao.Auth.authorize()
로 간편 로그인을 요청해야 한다.
Kakao.Auth.authorize()
를 통해 카카오계정 ID 및 비밀번호 입력 없이 카카오톡을 통해 사용자를 인증하고 인가 코드를 발급받을 수 있다.
코드는 아래와 같다.
// ✅ /src/KakaoLogin.js
const restkey = "본인 REST API 키";
if (!window.Kakao.isInitialized()) {
window.Kakao.init(restkey);
console.log(window.Kakao.isInitialized());
}
const handleKakaoSign = () => {
const redirectUri = `${window.location.origin}/callback/kakaotalk`;
const scope = [
"profile_nickname",
"profile_image",
"account_email",
"gender",
"age_range",
"birthday",
"friends",
"openid",
].join(",");
window.Kakao.Auth.authorize({
redirectUri,
scope,
});
};
공식문서에 따르면, redirectUri
는 인가 코드 발급을 전달받을 URI를 의미한다. 이는 우리가 처음에 등록한 Redirect URI
를 의미한다.
window.location.origin
은localhost:3000
을 의미한다.
위에서 설정한 동의 항목의 ID도 scope
에 전달해야 한다.
동의항목의 ID는 여기서 살펴보면 된다.
함수의 자세한 설명은 Kakao Developer에서 확인하자.
이제 버튼을 클릭하게 되면 카카오 간편 로그인을 수행하게 된다. 모든 과정이 끝나면 설정한 Redirect URI
에 query string
으로 인가 코드(code
)가 주어진다.
그 다음으로 URLSearchParams
를 사용하여 code값
을 가져온다.
// ✅ /src/Kakao.js
const params = new URL(document.location.toString()).searchParams;
const code = params.get("code");
이제 가져온 code
를 통해서 ID 토큰을 가져오면 된다.
토큰 가져오기에 대한 자세한 설명은 카카오 Developer에서 확인하자.
코드는 아래와 같다.
// ✅ /src/Kakao.js
const [idToken, setIdToken] = useState(null);
const [accessToken, setAccessToken] = useState(null);
const getKakaoToken = async (code) => {
await fetch("https://kauth.kakao.com/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `grant_type=authorization_code&client_id=${restkey}&redirect_uri=${window.location.origin}/callback/kakaotalk&code=${code}`,
})
.then((res) => res.json())
.then((data) => {
// OIDC 사용하는 경우 id_token으로 접근해야 한다.
if (data.id_token) {
setIdToken(data.id_token);
} else {
navigate("/");
}
if (data.access_token) {
setAccessToken(data.access_token);
window.Kakao.Auth.setAccessToken(data.access_token);
}
});
};
getKakaoToken
은 인자인 code
에 위에서 얻은 인가 코드를 넘겨서 호출하면 된다.
우리는 OpenID Connect를 통한 로그인 구현이므로 ID 토큰이 필요하다.
위에서 OpenID Connect 설정을 했으므로, 토큰을 요청했을 때 응답 데이터안에 ID 토큰이 함께 발급된다. ID 토큰은 응답 데이터 내부에서 id_token
으로 표시되며,
코드에서 data.id_token
을 의미한다.
Firebase와 연동할 때 ID 토큰을 사용한다는 점을 꼭 기억하자.
access_token
은 사용자의 프로필 이미지, 나이, 생일 등 여러 정보를 추후에 사용할 수도 있을 것 같아 일단 받아와서 설정은 해뒀다.
이제 Firebase에서 로그인 제공업체를 설정해야 한다.
이전에 했던 그대로 [내 프로젝트] → [Authentication] → [Sign-in method]로 이동하자.
새 제공업체 추가를 누르고 OpenID Connect 항목을 선택하자.
다음과 같은 설정이 표시되는데 아래와 같이 설정하자.
[카카오 로그인] → [보안] → [Client Secret 코드 발급]
)모두 작성했다면 추가로 작성해야 하는 코드가 있다.
웹 앱에서 OpenID Connect를 사용하여 인증을 살펴보자.
추가되어야 하는 코드는 다음과 같다.
// ✅ /src/Kakao.js
const provider = new OAuthProvider("oidc.kakao");
const credential = provider.credential({
idToken: idToken,
});
signInWithCredential(auth, credential)
.then((result) => {
const credential = OAuthProvider.credentialFromResult(result);
const acToken = credential.accessToken;
const idToken = credential.idToken;
}).catch((error) => {
// Handle error.
console.log(error);
});
위 코드는 콜백 페이지에 해당하는 js
파일에 작성했다. 나의 경우 Kakao.js
이다.
이렇게 모두 코드를 작성했다. 결과를 살펴보자.
짜잔, 카카오 로그인도 유저로 등록이 됐다!
근데 이렇게 만드는게 맞나 싶나? 하는 생각이 든다. 뭔가 하나씩 빠져있는 느낌?
Client Secret에 대한 처리도 하지 못했고, 그저 작동이 되는지 안되는지만 구현을 했기에... 이미 존재하는 유저가 로그인 했을 때 처리해주는 로직도 없다.
일단 작동은 확인했으니, 추가적으로 구현이 필요한 부분은 나중에 구현해보도록 하겠다.