Spring으로 블로그 서비스를 만들던 중, API Gateway 패턴을 도입하기로 결정하여 Spring Cloud에서 지원하는 Eureka + Gateway로 구조를 변경했습니다. 이때, 기존 Spring 서버는 Main 서비스로 명명하고 인스턴스로 등록되는 서버가 되었습니다.
그 이후로 구글 로그인을 시도하면, 400 : invalid_request 오류가 발생했는데 이때 Gateway 패턴이 도입되면서 Redirect Uri를 Gateway의 주소로 변경한 기억이 없어서 이 부분이 문제겠거니 하고 수정했었습니다.

기존 스프링 서버는 8000포트를 썼지만 Gateway는 8760포트를 쓰고 있고, predicates 조건으로 /main 경로를 쓰고 있어서 포트와 /login사이에 /main을 추가했습니다.
하지만, 그럼에도 불구하고 오류가 지속되었는데

[오류 세부정보]를 클릭해서 정확히 어디서 문제가 되는지 확인해봅니다.

저는 분명, RedirectUri를 http://localhost:8760/main/login/oauth2/code/google로 설정했지만 오류 메시지에서는 8000포트로 되어 있음을 확인할 수 있었습니다.
오류 원인으로 짐작할 수 있던 건 2가지 정도 였습니다.
첫번째는 시간이 지나면 명확해집니다. 10분 정도 기다려봤지만 해결되지 않아서 자연스럽게 원인은 두번째로 결정되었네요.
이제 어디서 문제가 생겼는지 찾아야 하는데...
결론적으로는 Spring OAuth2 Client에서 RedirectUri를 생성할 때의 {baseUrl}이 문제입니다. Default 값은 redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"과 같은데, 여기서 {baseUrl}은 말그대로 서버의 baseUrl입니다.
저는 Gateway 서버에서 OAuth2 로그인을 처리하지 않고, 마이크로서비스인 Main 서비스에서 처리하고 있습니다. 그렇다보니, RedirectUri를 생성하게 되면 http://localhost:8000/login/... 주소로 생성이 되어, 웹에서 설정한 RedirectUri와 서버에서 생성한 RedirectUri가 일치하지 않는 문제가 발생합니다.
그래서 해결방법은 기본값을 쓰지 않고, 직접 Uri를 지정하면 해결됩니다.
spring
security:
oauth2:
client:
registration:
google:
client-id: ${GOOGLE_CLIENT_ID}
client-secret: ${GOOGLE_CLIENT_SECRET}
redirect-uri: "http://localhost:8760/main/login/oauth2/code/{registrationId}"
scope: profile, email
이렇게 redirect-uri를 application.yml에서 직접 지정해주시면 해결됩니다.
local, production 환경에 따라 redirect-uri를 다르게 설정해야 하므로 Spring application.yml 관리하기 글을 참고하시면 좋습니다.