2025. 3. 14. 17:22ㆍSpringboot/security
전체코드 : https://github.com/gks930620/spring_securty_all
https://brilliantdevelop.tistory.com/226에 이어 jwt방식에 oauth2로그인을 적용해보겠다.
백엔드서버인 spring boot를 기준으로 설명한다.
예시는 카카오 로그인이다.
책임분배
Oauth2 로그인에서 프론트와 백엔드가 어떤 역할까지 수행할 건지에 문제이다.
프론트에서 인가코드만 백엔드로 전달할 것인지,
프론트가 access_token까지 얻은 후 백엔드로 전달할 것인지 등이다.
이전 글에서 했던 웹 seesion방식의 Oauth2 기능은 인가코드만 백엔드로 전달하는 형태였다.

보시다시피 웹 session방식에서는 백엔드가 인가코드-access token - 리소스서버 과정을
전부 담당하고 있다.
이런식으로 프론트가 인가코드만 백엔드에 전달하는 방식은 다음과 같은 장점이 있다.
- 보안성 증가: Access Token이 외부(클라이언트)에 노출되지 않음.
- 클라이언트의 부담 감소: 클라이언트는 인가 코드만 받아서 서버로 넘기면 되므로 구현이 단순해짐.
- 토큰 관리가 서버에서 일관되게 이루어짐
여기서도 프론트가 인가코드만 백엔드에 전달하는 방식을 사용한다.
또 일반적으로 spring boot와 security를 사용하는 백엔드중심서비스에서는 이 방식을 사용한다.
동작방식
클라이언트가 로그인버튼 클릭

먼저 클라이언트가 localhost:8080/custom-oauth2/login/kakao에 요청한다.
웹 세션방식에서는 /oauth2/authorization/kakao주소인데 이는 security가 기본적으로 인식하는 URL이다.
/oauth2/authorization/kakao로 요청을 하면 security는 클라이언트에게
authorization-uri : https://kauth.kakao.com/oauth/authorize 로 redirect하는게 기본 동작이지만
브라우저가 아닌 JWT방식에서는 클라이언트에게 redirect 를 하게 할 수는 없다.
그래서 security 기본동작이 실행되지 않게 /custom-oauth2/login/kakao로 요청하고
Controller에서 원하는 동작을 작성해야 한다.
이 Controller에서 해야 할 일들이
OAuth2AuthorizationRequest객체 저장하기 + 클라이언트한테 URL전달하기이다.
※ Oauth2AuthorizationRequest객체는 ID,pw 입력한 클라이언트,
인가코드로 로그인요청하는 클라이언트 등을 백엔드에서 확인하는 객체이다.
(A는 ID,pw를 입력했고, 카카오로부터 인가코드를 얻었는데 , B가 A의 인가코드를 얻어서 로그인신청하는상황 등)
클라이언트가 카카오서버 로그인페이지 요청

서버로부터 받은 authorizationURL로 카카오서버에 로그인페이지를 요청한다.
이 부분은 클라이언트가 알아서 하면 된다.
클라이언트가 ID,PW입력 후 카카오서버로부터 인가코드 받기

클라이언트가 redirect -uri로 백엔드서버에 요청

이 때 클라이언트는 인가코드, state등을 포함해서 요청해야 한다.
이 state 값이 처음의 저장한 Oauth2AuthorizationRequest를 식별하는데 쓰임
이제 본격적인 백엔드과정에서 로그인과정이 진행된다
백엔드서버에서 카카오 Oauth2 로그인과정

그림과 같이 Oauth2AuthorizationRequest를 검사 (같은 클라이언트인지 검사)를 했다면
인가코드로 토큰요청 -> access token 획득 ->UserRequest요청 -> 유저정보 획득
-> CustomOauth2UserDetailsService 실행 및 로그인정보객체 return 까지.
웹 session방식의 Oauth2로그인방식과 차이가 없다.
결국 카카오서버로부터 유저정보 얻어서 우리서버DB에 저장을 하게 될 뿐이다.

이후 successHandler에 의해 로그인성공에 관한 jwt발급을 해주면 된다.
로그인성공 후 access token을 이용한 로그인

로그인 성공 이후라면 어차피 카카오로 로그인한 유저정보가 우리서버DB에 저장되어있다.
그래서 이후에는 https://brilliantdevelop.tistory.com/226 와 같이 똑같이
access token, refresh토큰을 보내면 된다.