Spring OAuth2 JWT방식(1) - 개요
강의를 들은 내용을 토대로 블로그를 작성.
OAuth2.0 Client와 Spring Security 6 Framework를 활용하여 소셜로부터 인증을 받고 전달받은 유저 데이터를 활용하여 JWT를 발급하고 인가를 진행하는 내용을 코드와 함께 정리해볼 예정이다.
구현 방식은 API 서버 형태로 구현하고, 소셜서비스는 구글, 카카오, 애플 3개로 진행할 예정이다.
소셜 로그인 후 JWT를 발급받고, JWT를 통한 경로별 접근 권한과 인증 정보를 DB에 저장후 추가 정보를 기입하는 방식.
사용하는 버전과 의존성
- Spring Boot 3.2.3
- Spring Security 6.2.2
- OAuth2 Client
- Lombok
- Spring Data JPA - MySQL
- JJWT 0.12.3
- Gradle - Groovy
동작 원리와 front/back 책임 분배
OAuth2 Code Grant 방식의 동작 순서
- 로그인 페이지
- 성공 후 코드 발급
- 코드를 통해 액세스 토큰 요청
- 액세스 토큰 발급 완료
- 액세스 토큰을 통해 유저 정보 요청
- 유저 정보 획득 완료
JWT방식에서는 로그인이 성공하면 JWT발급 문제와 웹/하이브리드/네이티브앱 별 특징에 의해 OAuth2 Code Grant 방식 동작의 책임을 어디에 둘 것인지 많은 고민을 하게 된다.
- 로그인(인증)이 성공하면 JWT를 발급해야 하는 문제
- 프론트 단에서 로그인 경로에 대한 하이퍼링크를 실행하면 소셜 로그인창이 등장하고 로그인 로직이 수행된다.
- 로그인이 성공되면 JWT가 발급되는데 하이퍼링크로 실행했기 때문에 JWT를 받을 로직이 없다. (해당 부분에 대해 redirect_url 설정에 따라 많은 고민이 필요하다)
- API Client(axios, fetch)로 요청 보내면 백엔드측으로 요청이 전송되지만 외부 서비스 로그인 페이지를 확인할 수 없다.
- 웹 / 하이브리드 / 네이티브앱 별 특징에 대한 문제
- 웹에서 편하게 사용할 수 있는 웹페이지가 앱에서는 웹뷰로 보이기 때문에 UX적으로 좋지 못한 상황이 될 수 있다.
- 앱 환경에서의 쿠키 소멸 현상이 발생한다.
위와 같은 문제로 인터넷에는 잘못된 구현 방법들이 무수히 많이 떠돌고 있다.
프론트와 백의 책임 분배
1. 모든 책임을 프론트가 맡는 방법
프론트단에서 로그인-> 코드 발급 -> 액세스 토큰 -> 유저 정보 획득 과정을 모두 수행하고, 유저 정보를 백엔드로 보내 JWT를 가져오는 방법이다.
문제점 : 백엔드가 받는 유저 정보를 검증해야 하므로 추가적인 보안 로직이 필요하다.
2. 책임을 프론트와 백엔드가 나누어 가지는 방법(잘못된 방식)
프론트단에서 로그인-> 코드 발급 까지만 수행하고,
코드를 백엔드로 전송 후 백엔드단에서 코드-> 토큰 발급 -> 유저정보 획득 -> JWT발급하는 방식이다.
많은 웹 블로그가 이러한 방식으로 구현되어 있지만 이는 잘못된 구현 방법이다. (보안 규격에 어긋남)
3. 모든 책임을 백엔드가 맡는 방법
프론트단에서 백엔드의 OAuth2 로그인 경로로 하이퍼링킹을 진행 후 백엔드단에서 로그인페이지요청 -> 코드발급 -> 토큰요청-> 토큰발급-> 유저정보 획득 -> JWT발급 순서로 주로 웹앱 / 모바일앱 통합 환경 서버에서 사용하는 방식.
-> 백엔드에서 JWT를 발급하는 방식의 고민과 프론트엔드에서 받는 로직을 처리해야 한다.
이 실습에서 구현할 방식은 모든 책임을 백엔드가 맡는 방식으로 할 것이다.