요즘 개발할 시간이 없어서
새벽에 틈틈히 개발을 하고 있어요.
오늘은 카카오 로그인을 구현하려고 해요
카카오 로그인 구현하기
1. 초기 설정
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
에서 애플리케이션을 추가해야 합니다.
로그인 후 내 애플리케이션 > 애플리케이션 추가하기를 눌러 등록해주세요.

2. 플랫폼 등록
내 애플리케이션 > 앱 설정 > 플랫폼 에서 플랫폼을 등록할 수 있어요.
저는 웹만 사용할거기 때문에 웹만 등록하겠습니다.

테스트 환경에서 사용되는 프론트 도메인을 적어줬습니다.
또한 카카오 로그인 사용 시 Redirect URI를 등록해주어야 해요.

먼저, 카카오 로그인을 활성화 시켜줍니다.

이후 아래로 내리면 Redirect URI를 적는 부분이 나와요.
저는 백엔드 서버에서 처리할거기 때문에, 백엔드 API 엔드포인트를 적어주었어요.

3. 구현하기
카카오 로그인은 다음과 같은 방식으로 진행됩니다.

인가 코드 받기
먼저 프론트 쪽에서 REST_API_KEY와 REDIRECT URL을 사용해 로그인 요청을 보냅니다
REST API KEY 는 카카오 개발자 대시보드 > 내 애플리케이션 > 앱 설정 > 앱 키에서 확인할 수 있습니다.
let REST_API_KEY = import.meta.env.VITE_KAKAO_REST_API_KEY;
let REDIRECT_URI = kakaoUrl;
const kakaoToken = `https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}`;
<button className="login-button kakao-button" onClick={() => window.location.href = kakaoToken}>
<img src={KakaoIcon} alt="카카오 로그인" style={{ width: '24px', height: '24px' }}/>
<span className='fontS-12'>카카오로 시작하기</span>
</button>
토큰 받기
이렇게 되면 카카오 서버에서 클라이언트에게 로그인 요청을 보내고, 사용자가 로그인을 완료하면 아까 설정한 Redirect URI로 인가코드를 보내게 됩니다.
저는 Redirect URI를 서버로 설정해놓았기 때문에 서버에서 다음과 같은 코드를 작성합니다.
router.get("/", async (req, res) => {
let REST_API_KEY = process.env.KAKAO_REST_API_KEY;
let REDIRECT_URI = "http://localhost:3000/api/oauth/kakao";
const FRONTEND_URL = "http://localhost:5173"; // 프론트엔드 URL
// 카카오 로그인 시, 쿼리스트링으로 전달되는 CODE의 값(인가코드)
let code = req.query.code;
try {
// 1. 액세스 토큰 받기
const tokenResponse = await axios.post("https://kauth.kakao.com/oauth/token", null, {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
params: {
grant_type: "authorization_code",
client_id: REST_API_KEY,
redirect_uri: REDIRECT_URI,
code: code,
},
});
const access_token = tokenResponse.data.access_token;
// 2. 사용자 정보 가져오기
const userResponse = await axios.get("https://kapi.kakao.com/v2/user/me", {
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
},
});
const userData = userResponse.data;
// 3. MongoDB에 사용자 정보 저장 또는 업데이트
const userInfo = {
platformId: userData.id.toString(),
platform: "kakao",
email: userData.kakao_account.email,
lastLogin: new Date(new Date().getTime() + (9 * 60 * 60 * 1000)) // 한국 시간으로 변환
};
const user = await User.findOneAndUpdate(
{ platformId: userInfo.platformId },
userInfo,
{ upsert: true, new: true }
);
// 4. 프론트엔드로 리다이렉트하면서 사용자 정보 전달
const userDataForFrontend = {
id: user._id,
platformId: user.platformId,
email: user.email,
platform: user.platform,
access_token: access_token // 프론트엔드에서만 사용하기 위해 전달
};
// URL 파라미터로 사용자 정보 전달
const queryParams = new URLSearchParams(userDataForFrontend).toString();
res.redirect(`${FRONTEND_URL}/login/success?${queryParams}`);
} catch (error) {
console.error("카카오 로그인 에러:", error.response?.data || error.message);
// 에러 발생 시 프론트엔드로 리다이렉트
res.redirect(`${FRONTEND_URL}/login/error?message=${encodeURIComponent("로그인 처리 중 오류가 발생했습니다.")}`);
}
저는 로그인 정보를 mongodb에 저장하는 것 까지 추가하였습니다.
사용자 로그인 처리
React의 AuthProvider를 사용해서 로그인 처리를 했습니다.
import React, { createContext, useState, useContext, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
const AuthContext = createContext(null);
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [isAuthenticated, setIsAuthenticated] = useState(false);
const navigate = useNavigate();
useEffect(() => {
// URL에서 로그인 정보 확인
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const platformId = urlParams.get('platformId');
const platform = urlParams.get('platform');
const access_token = urlParams.get('access_token');
const email = urlParams.get('email');
if (id && platformId && platform && access_token) {
const userData = {
id,
platformId,
platform,
email
};
setUser(userData);
setIsAuthenticated(true);
localStorage.setItem('user', JSON.stringify(userData));
localStorage.setItem('access_token', access_token);
// URL 파라미터 제거하고 홈으로 리다이렉트
window.history.replaceState({}, document.title, window.location.pathname);
navigate('/');
} else {
// 로컬 스토리지에서 사용자 정보 확인
const storedUser = localStorage.getItem('user');
const token = localStorage.getItem('access_token');
if (storedUser && token) {
setUser(JSON.parse(storedUser));
setIsAuthenticated(true);
}
}
}, [navigate]);
const logout = () => {
localStorage.removeItem('user');
localStorage.removeItem('access_token');
setUser(null);
setIsAuthenticated(false);
};
return (
<AuthContext.Provider value={{ user, isAuthenticated, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};
'연습장' 카테고리의 다른 글
UI 디자인에 자신이 없으면?? - 피그마 플러그인 [Layermate] (0) | 2025.05.22 |
---|---|
프로그래머스 PCCE 시험 후기 (0) | 2025.05.19 |
내 사이트에 광고 넣기 [ 구글 애드센스 ] (0) | 2025.05.18 |
네이버 검색 엔진에 내 사이트 등록하기 (1) | 2025.05.15 |
구글 서치 콘솔에 내 홈페이지 등록하기 (0) | 2025.05.15 |