상세 컨텐츠

본문 제목

[SpringBoot+React+JWT+카카오 로그인] 카카오 로그인

WEB/스프링

by 비행학교브론즈 2024. 8. 29. 11:14

본문

[아직 작성중입니다..]

 

쉽게 할 줄 알았는데 생각보다 오래 걸려서 작성합니다.

오류도 많고 허점이 많은 코드이니 참고만 하시고 수정해서 사용하시길 바랍니다. 

JWT 구현에 대한 초기 설정은 생략합니다. 

(개발자 유미님의 기초적인 JWT 설정 참고)

https://www.youtube.com/watch?v=NPRh2v7PTZg&list=PLJkjrxxiBSFCcOjy0AAVGNtIa08VLk1EJ


[1. 개요]

카카오 로그인 시스템 인증 및 인가를 카카오 인증서버에 대신 맞겨 최소한의 정보만으로 유저를 구별한다. 


[2. 환경]

spring boot 2.6.15, spring dta jpa, jjwt 0.11.2(json web token), react, fetch api. 


[3. 관련 카카오 정식 문서]

개요: 

https://developers.kakao.com/docs/latest/ko/kakaologin/common

RestAPI로 구현 가이드:

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api


[4. 카카오 로그인 설정]

Kakao developers 에 접속 후 내 애플리 케이션 등록 -> 

로그인 ON, 동의항목 설정, Redirect URI 설정.

(더 깔끔한 로그인 구현을 위해 문서를 읽어보시고 나머지 항목도 설정하시는 것 추천드립니다)

 

1) 전체 설정

 

2) 카카오 로그인 설정

사용자 정보를 받기 위해서 OpenId Connection도 활성화 해줍니다.

 

3) 동의 항목 설정

이메일이 선택 동의로 되어있지만, 정식 서비스시에 카카오의 심사를 받은 후 필수 동의로 되어있다고 간주하고 진행합니다. 

 

4) Redirect URI 설정

사용자가 카카오 인증 서버에서 로그인, 인가 받은 후 요청할 react server 서버에서 라우팅된 url을 적어줍니다. 


[5. 관계도]

 


 

[선택사항]

 

생략함. 

 

이유: 

1. 이 단계에서의 redirect할 주소는 카카오 인증 서버이기 때문에 결국 사용자(브라우저)가 인증 서버에 직접 요청하는 것이나 다름없습니다. 

2. 이미 필요한 정보가 이미 qeury string에 노출됩니다. 

그래도 구현 하면 좋을 이유

1. clinet_id, rediect_url 등 APIServer(SpringServer) 한곳에서 관리 할수 있어 관리가 용이할 수 있습니다.

 

[인가코드받기(이사용자 카카오가 인증한 사용자임)]

 

1 : 카카오 서버가 요청을 구분하기 위해 client_id(어느 서버에 로그인을 요청하는지 식별 == 나의 API KEY), 카카오에서 사용자 인증, 인가 후에 사용자를 redirect 시킬 redirect_uri를 보냅니다. 

<a href={"https://kauth.kakao.com/oauth/authorize" +
  "?client_id=" + API_KEY +
  "&redirect_uri=" + LOGIN_REDIRECT_URI +
  "&response_type=code"}>
  카카오 로그인
</a>

 

2 ~ 6: 카카오 서버는 인증 인가를 위해 로그인 페이지를 반환하고 사용자는 로그인 정보를 보냅니다.

지금까지 clinet_id(어떤 플랫폼인지 == API_KEY로 구분), 카카오 회원 정보, redirect_uri(인증 인가 끝난 후 redirect시킬 주소)를 전달 받은 카카오 인증 서버에서는받은 정보를 조합해 특정플랫폼(내가 만든 서비스)에 대한 카카오 회원의 인증, 인가를 진행합니다. 

그리고 로그인이 성공하면 동의화면을 반환하며 사용자는 동의사항을 체크합니다. 

 

카카오가 redirect한 로그인 화면, 동의 화면

 

7~12: 

이후 사전에 설정에 redirect_url로 redirect 응답을 보내고 브라우저는 그에 따라 React Server에

get 요청을 하게 됩니다. 

이때 query string 으로 인가 코드를 받게 됩니다.

응답 실패시 query string으로 error가 넘어 오므로 이에 따라 사용자에게 로그인 안내요청 또는 카카오 회원가입 페이지 등

서비스 목적에 맞게 안내해야합니다.

 

리다이렉트 된 페이지 

 

리다이렉트된 페이지 코드

const KaKaoCallback = () => {
    
    return <>
    <h1>Loading</h1>
  </>
}

 

 

15~17:

useEffect redirect된 페이지에서 바로 서버로 요청합니다. 

 

const KaKaoCallback = () => {
	//useEffect등을 사용해 redirect되자 마자 API서버에 코드 전달
    useEffect(() => {
		//parameters 받기
        const code = new URL(window.location.href).searchParams.get("code");
        const error = new URL(window.location.href).searchParams.get("error");
        const errorDescription = new URL(window.location.href).searchParams.get("error_description");
        const state = new URL(window.location.href).searchParams.get("state");
		
        //body 만들기
        const body = {};
        if (code) {
          body["code"] = code;
        }
        if (error) {
          body["error"] = error;
        }
        if (errorDescription) {
          body["errorDescription"] = errorDescription;
        }
        if (state) {
          body["state"] = state;
        }
    
        jsonBody = JSON.stringify(body);
        
        //SpringServer(APIServer)로 인가 코드 전달
        requestLogin(body);
    }, []);
    
    //fetch api로 만든 request method
    const requestLogin = (body) => {

        fetch("/auth/login/kakao", {
          method: "POST",
          headers: {"Content-Type": "application/json"},
          body: body
        })
          .then((resp) => {
            if (resp.ok) {
                //Login시 Session처리, Cookie 처리 // LocalStorage token 처리 등등
                resp.json().then(data => login(localStorage, data.body));
                window.location.href = "/";
            } else {
        //로그인 요청 실패시 작업	
            }
        });
    }
    
    return <>
    <h1>Loading</h1>
  </>
}

관련글 더보기