문제 상황
앱에서 소셜 로그인을 진행했을 때, authorization_request_not_found 에러를 응답 받았다.
다만 조금 특이한 상황에서 발생했는데,
1) 소셜 로그인 화면에서 로그인까지는 성공. 그 이후에 에러 리턴
2) 한번 실패한 후에 브라우저에 로그인 기록이 남아있는 채로 다시 로그인하면 정상적으로 응답
원인
우선 authorization_request_not_found이 어디서 발생하는 곳은 OAuth2LoginAuthenticationFilter의 attemptAuthentication 메서드입니다.

SpringSecurity의 OAuth2 로그인 동작 원리
1. 프론트에서 서버로 소셜 로그인 요청
2. 서버에서 소셜로그인 주소를 리턴. 이때 리다이렉트 주소를 서버로 설정
3. 사용자가 로그인 진행
4. 프로바이더가 인증 코드을 발급하여 서버로 리턴
5. 서버에서 인증 코드를 가지고 Access Token을 발급받아, 이를 통해 가지고 리소스 서버에서 필요한 정보(메일 주소 등 )을 요청
6. 리소스서버에서 서버로 요청한 정보를 리턴
7. 서버에서 이 정보로 로그인 작업을 수행
8. 프론트로 로그인 성공 리턴
크게 보면 위와 같은 순서로 소셜 로그인이 진행됩니다. 이때 위의 2번에서 스프링 시큐리티가 요청 정보를 저장하는 작업을 합니다. 그리고 이 작업은 AuthorizationRequestRepository의 saveAuthorizationRequest 메서드에서 OAuth2AuthorizationRequest 객체를 저장합니다. 기본적으로는 AuthorizationRequestRepository의 구현체인 HttpSessionOAuth2AuthorizationRequestRepository에서 진행하는데, 이름에서 알 수 있듯이 Session에 저장하는 방식이며 Customize가 가능합니다.
그리고 4번에러 프로바이더로 부터 인증코드를 응답받으면, 위에서 저장했던 OAuth2AuthorizationRequest 객체를 확인하는 작업을 하는데, 이 작업이 위 사진에 나오는 attemptAuthentication 메서드의 일부입니다. 이때 해당하는 객체가 없다면 authorization_request_not_found 에러를 뱉게 되고, 마찬가지로 위의 AuthorizationRequestRepository의 구현체가 이 작업을 수행합니다.
따라서 OAuth2AuthorizationRequest객체를 잘 저장했는지 확인하는 것이 중요합니다.
AuthorizationRequestRepository 구현체
저의 경우에는 Session에 저장하기 보다는 Cookie에 저장하는 하기 위해 따로 Custom을 했습니다. 왜냐하면 Session은 나중에 다중 서버를 운영하게 될 때 확장성이 떨어지기 때문입니다.
저는 쿠키를 설정할 때, 쿠키의 만료 시간을 10초로 지정해 놓는 게 문제였습니다. 사용자가 로그인을 10초 안에 하지 못하면 쿠키가 만료되어 해당 문제가 발생했습니다. 따라서 이 시간을 늘려서 문제를 해결했습니다.
이 에러의 경우는 AuthorizationRequestRepository 구현체를 어떻게 구현했는지에 따라 해결 방법이 다르지만, OAuth2AuthorizationRequest 객체를 어떻게 저장하고 찾는지를 확인하는 게 중요할 것 같습니다. 따로 커스텀하지 않았다면 분산 서버 환경에서 Session 정보를 찾지 못해 문제가 발생하는 경우가 많은 것 같습니다.
참조
'Back-end > Spring Boot' 카테고리의 다른 글
| [DDD] SpringBoot에서 Repository 추상화하기 (0) | 2023.08.08 |
|---|---|
| SpringBoot 3.1의 ConnectionDetails abstraction (0) | 2023.08.01 |
| SpringBoot 3.1의 Docker Compose (0) | 2023.08.01 |
| Entity의 PK은 Wrapper Type? Primitive Type? (1) | 2023.01.29 |
| [애러해결] Could not resolve all files for configuration ':classpath'. (0) | 2023.01.27 |