L-ilac / springboot-tutorials

0 stars 0 forks source link

카카오 OAuth2 로그인 트러블 슈팅 #4

Open L-ilac opened 1 year ago

L-ilac commented 1 year ago

스프링 시큐리티에서 사용하는 많은 filter 들이 존재하지만, 직접적인 OAuth2 로그인과 관련된 필터는 아래의 두 개이다.

  1. OAuth2AuthorizationRequestRedirectFilter
  2. OAuth2LoginAuthenticationFilter

OAuth2AuthorizationRequestRedirectFilter 에서 OAuth2 로그인을 위한 최초 요청 필터링을 수행한다.

OAuth2LoginAuthenticationFilter 클래스에서 authorization code로 Access Token을 요청하는 로직이 자동으로 수행된다.

  1. OAuth2LoginAuthenticationFilter 클래스의 attemptAuthentication()
  2. ProviderManager 클래스의 authenticate()
  3. OAuth2LoginAuthenticationProvider 클래스의 authenticate()
  4. OAuth2AuthorizationCodeAuthenticationProvider 클래스의 authenticate()
  5. authenticate() 내부의 getTokenResponse()
  6. DefaultAuthorizationCodeTokenResponseClient의 getTokenResponse()
  7. getTokenResponse() 내부의 getResponse()
  8. getResponse() 내부의 exchange()
  9. exchange() 내부의 doExecute() -> authorization code로 access token을 받아오는 실제 http 요청을 만들고 날림. 응답 받아옴
L-ilac commented 1 year ago

yml 파일에서 client-authentication-method : client-secret-post -> client_secret_post로 수정하니 해결됐음. 오타가 문제였다.

L-ilac commented 1 year ago

구글과 네이버는 Access Token을 갖고 올 때 authorization_code 는 request body에 넣고, client-id와 client-secret은 인코딩해서 request header에 Authorization 헤더로 값을 넣는다. (client_secret_basic 방식)

카카오는 Access Token을 갖고 올 때 authorization_code, client-id, client-secret 모두 request body에 Content-type: application/x-www-form-urlencoded;charset=utf-8 형태로 넣는다. (client_secret_post 방식)

카카오는 authorization code를 통해 Access Token을 갖고 올때, 개발자 페이지에서 client-secret이 활성화 되어있다면, 필수적으로 해당 값을 보내줘야한다. 그 값을 보내주지 않으면 Access Token을 발급해주지 않음.

L-ilac commented 1 year ago

OAuth2AuthorizationCodeGrantFilter <-- 이 녀석은 무슨 역할을 하는 건지 다시 알아볼 필요가 있다.

OpenID Connect Authentication using the Authorization Code Flow - http.oauth2Login() - OAuth2LoginAuthenticationFilter OAuth 2.0 Authorization Code grant - http.oauth2Client().authorizationCodeGrant() - OAuth2AuthorizationCodeGrantFilter

https://stackoverflow.com/questions/54900696/oauth2authorizationcodegrantfilter-vs-oauth2loginauthenticationfilter-in-spring

L-ilac commented 1 year ago

Oauth2 로그인이 성공하면, AbstractAuthenticationProcessingFilter 에 의해서 SecurityContextHolder에 Authentication 저장된다.

L-ilac commented 1 year ago

(혹시나 그냥 서버에서 둘 다 하면 안되나요? 라고 할 수도 있는데, 저는 안됐었습니다. CORS 오류가 미친듯이 발생하였고 결국 실패했습니다. 이후 방법을 찾아보니, 프론트와 백을 분리해서 진행하는 경우에는 프론트에서 AccessToken까지 받아오고, 백은 해당 AccessToken을 통해 정보를 조회하는 방식으로 진행하는 것이 정석인 것 같았습니다)