티스토리 뷰
이 글은 OAuth2 구현을 소개하는 글은 아니다, SpringBoot OAuth2 구현은 이미 훌륭하게 작성된 예제 코드가 많다
구글에 검색했을 때 대부분의 OAuth2 구현은 callicoder.com에서 소개된 예제를 기반으로 만들어져 있다
나도 callicoder.com을 참고해 OAuth2를 구현하였고 코드를 자세하게 이해하기 위해,
또한 가독성 향상을 위해 여러 번의 리팩토링을 거쳐서 코드는 조금 다를지라도 흐름은 거의 비슷하다
아래 블로그는 한국어로 친절하게 설명되어 있어 구현하는데 어려움이 없을 것이다
https://www.callicoder.com/spring-boot-security-oauth2-social-login-part-2/
오늘 만난 문제는 잘못된 쿠키 저장으로 인해 OAuth2 로그인이 터져버린 것이다
스프링은 기본적으로 HttpSessionOAuth2AuthorizationRequestRepository으로 OAuth2Request를 저장한다
나는 JWT를 사용하여 로그인을 관리하기 때문에 Session 방식을 사용하지 않아
예제 코드와 마찬가지로 HttpCookieOAuth2AuthorizationRequestRepository를 만들어 진행했다
HttpCookieOAuth2AuthorizationRequestRepository는 이름에서도 알 수 있듯이
OAuth2Request 객체를 쿠키에 저장하는 역할을 하는데 실제 회원 관리는 OAuth2UserService에서 담당하기 때문에
잠깐 동안만 정보를 가지고 있으면 되기 때문에 Cookie를 이용하는 방식이다
Spring Security에서 기본 제공되는 OAuth2LoginAuthenticationFilter에 의해 OAuth2 login flow가 흘러간다
잘못된 쿠키 저장으로 인한 문제는 168번째 줄의 authroizationRequest null check 시 나타난다
쿠키에서 정보를 가져오는데 현재 Localhost에 저장된 쿠키가 없으므로 authroizationRequest == null인 상태이고
OAuth2AuthenticationException이 터지게 된다
이 와중에 Google 로그인 화면으로 넘어가는 것까지는 가능했는데 이는 OAuth2와 OIDC의 차이로 생각된다
나도 이해를 아직 못 했고 간단하게 쓸만한 분량이 아니기 때문에 이 글에서는 두 방식의 차이에 대해서는 다루지 않겠다
OIDC가 조금 더 통합적이고 OAuth2에서 한번 더 업그레이드된 것이라 생각하면 된다
아래 코드는 문제의 핵심이 된 부분이다
CookieUtils라는 유틸 클래스에서 쿠키를 저장하기 전 쿠키에 여러 가지 세팅을 해주는 메서드인데
setSecure는 SSL 통신 시에만 쿠키를 저장하게 하는 것이고
setHttpOnly는 자바스크립트에서는 쿠키를 꺼낼 수 없도록 하는 것이다
setDomain은 쿠키를 저장할 서버를 Domain으로 지정하는 것이다
public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setMaxAge(maxAge);
cookie.setDomain("my-project");
response.addCookie(cookie);
}
setDomain에 관한 이해가 부족해 어이없게도 쿠키를 올바르게 저장할 수 없던 것이다
그저 서버 이름 정도 저장하는겠거니 하고 생각 없이 setDomain을 사용했는데 쿠키 저장 서버를 지정하는 메서드였다
이 메서드는 자신의 상위 도메인까지 설정할 수는 있지만 다른 서버를 지정할 순 없다
예를 들어 tistory.com, blahblah.tistory.com과 같은 도메인이 있을 때
blahblah.tistory.com에서 생성되는 쿠키를 tistory.com에 넣을 순 있지만 google.com 에는 넣을 수 없다
나는 localhost:port 형식으로 개발 중이었는데
뜬금없게 my-project라는 도메인을 넣었으니 쿠키가 저장될 수가 없었던 것이다
생각 없이 작성하지 말자.. 모르면 쓰지 말자
'Spring > Spring Security' 카테고리의 다른 글
[Filter] 빈으로 등록한 Custom Filter 사용 주의 (0) | 2022.03.17 |
---|---|
[OAuth2] 구글 로그인이 안 된다면 (0) | 2022.02.13 |
[JWT] 회원 아이디 & 비밀번호 찾기 feat. coolsms-api (0) | 2021.11.06 |
[JWT] jwt 로그아웃 구현 (0) | 2021.11.04 |
[OAuth2] /oauth2/authorization/github 404 (0) | 2021.10.23 |