포스트

JWT + 카카오 소셜 로그인 (4)

Login Flow Chart React + SpringBoot + Kakao 소셜 로그인 동작 과정

📌 Client Side

1. 카카오 로그인 클릭 ➡ 카카오 서버에 인가코드 요청

1
2
3
<a href={KAKAO_AUTH_URL}>
  <img src={icons.kakaoLogin} alt="KakaoLogo" className="kakao-login-icon" />
</a>
1
2
3
4
const CLIENT_ID = import.meta.env.VITE_KAKAO_CLIENT_ID;
const REDIRECT_URI = import.meta.env.VITE_KAKAO_REDIRECT_URI;

export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;

🐰 카카오 서버에 앱 키와 Redirect URI, 응답 유형을 포함하여 인가 코드를 요청하는데 이 요청은 사용자가 카카오 로그인 페이지에서 인증 및 동의를 완료한 후, 설정된 Redirect URI로 인가 코드를 전달받기 위한 것

2. 설정한 Redirect URI인 /login/oauth2/callback/kakao 경로로 리다이렉션 하기 위한 KakaoCallback 컴포넌트 라우트 설정

1
2
3
4
<Route
  path="/login/oauth2/callback/kakao"
  element={<KakaoCallback setIsLoggedIn={setIsLoggedIn} />}
/>

3-1. 렌더링한 KakaoCallback 컴포넌트에서 인가 코드 추출 및 사용자 처리

이 컴포넌트에서는 URL에 포함된 인증 코드를 추출하여 백엔드 서버에 액세스 토큰을 요청하고, JWT 토큰을 받게되면 로컬 스토리지에 저장하고, 로그인 처리를 업데이트 한 후 메인 홈으로 네비게이션한다.

코드 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
useEffect(() => {
  const fetchKakaoToken = async () => {
    const code = new URLSearchParams(location.search).get("code");
    if (code) {
      try {
        const response = await KakaoService.getAccessToken(code);
        const token = response.token;
        if (token) {
          localStorage.setItem("token", token);
          setIsLoggedIn(true);
          navigate("/");
        } else {
          console.error("로그인 실패:", response.message);
        }
      } catch (error) {
        console.error("카카오 로그인 에러:", error);
      }
    }
  };
  fetchKakaoToken();
}, [location, navigate, setIsLoggedIn]);

3-2. 백엔드 서버로 인가 코드 전달

KakaoService는 인가 코드를 백엔드 서버로 전달하여 액세스 토큰을 요청

코드 보기
1
2
3
4
5
6
7
8
9
10
11
static async getAccessToken(code) {
    try {
      const response = await axios.get(
        `${KakaoService.BASE_URL}/login/kakao?code=${code}`
      );
      return response.data;
    } catch (error) {
      console.error("로그인 실패: ", error.message);
      throw new Error("로그인 실패: " + error.message);
    }
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.