카카오 서버가 client 에게 너는 로그인을 성공했으니 code를 들고 localhost:8080/login/~/kakao 로 점프하라는 의미로
localhost:8080/login/~/kakao?code=zzzzzz_code 로 redirect 하는 response 를 건네준다
4. 사용자는 code 를 들고 우리 서버의 인증 end_point 로 오면 oauth2-client 다음 일들을 대신 수행해준다
authentication_code (code) 를 kakao_authorization_server 로 보내 access_token 을 발급받아온다
access_token 을 가지고 kakao_resource_server 로 설정한 scope 내의 접근정보만을 요청하여 받아온다
유저의 프로필 (이메일 , 이름) 등을 가져옴
5. 유저의 프로필과 이름을 DB에 저장하여 새로 유저로 등록하거나 조회한다
여기서 user entity 가 확인되면 loadUser 메서드에서 반환한 사용자 정보가 Spring security 가 관리하는 context 안 Authenticaton 객체로 접근이 가능하다
7. Authentication 객체가 조회되면 security oauth2 필터 의 successhandler 로 진입
Authenticaton 의 확인을 통해 어느 handler 로 진입할지 판단
8. successhandler 에서 jwt 를 생성한다
jwt 를 사용자에게 줄때 addCookie 를 사용하여 브라우저 쿠키에 저장하여주고
localhost:8080/ root 페이지로 이동하게끔 redirect 를 걸어준다.
jwt token 을 만들기 까지 resource_owner(사용자) 는 4번이후로 blocking 상태이다
기존 코드에서 바뀐 점
addCookie 를 하는 Util 추가
Cookie 를 줄때 httpOnly 는 false 로 설정해야한다 ( rest api 서버이므로)
AuthenticationSuccessHandler 대신 SimpleUrlAuthenticationSuccessHandler 를 사용하였음
왜 SimpleUrlAuthenticationSuccessHandler 를 사용해야 하는지?
SimpleUrlAuthenticationSuccessHandler 는 AuthenticationSuccessHandler 를 구현해놓은 스프링 시큐리티에서 default 로 제공되는 구현체임
스프링시큐리티 안에서 redirect 를 할경우 관련 메서드를 사용해야함
public class SimpleUrlAuthenticationSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
implements AuthenticationSuccessHandler {
AbstractAuthenticationTargetUrlRequestHandler 에서 제공되는 DefaultRedirectStrategy.class 가 redirect 를 제공해준다
AbstractAuthenticationTargetUrlRequestHandler 안에는 DefaultRedirectStrategy.class 가 제공됨
DefaultRedirectStrategy.class 에서 사용하는
response.encodeRedirectURL 부분이 우리의 기존 설정과 다른점인것같음
정확하게 왜 기존 방식의 handler 는 안됬는지는 모르겠다..
public class DefaultRedirectStrategy implements RedirectStrategy {
/**
* Redirects the response to the supplied URL.
* <p>
* If <tt>contextRelative</tt> is set, the redirect value will be the value after the
* request context path. Note that this will result in the loss of protocol
* information (HTTP or HTTPS), so will cause problems if a redirect is being
* performed to change to HTTPS, for example.
*/
@Override
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
String redirectUrl = calculateRedirectUrl(request.getContextPath(), url);
redirectUrl = response.encodeRedirectURL(redirectUrl);
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Redirecting to %s", redirectUrl));
}
response.sendRedirect(redirectUrl);
}
successhandler 로직 수정
OAUTH 2 LOGIN FLOW [최종안]
1. 사용자가 소셜로그인 버튼을 누른다
2. 소셜로그인 제공페이지 (https://kauth.kakao.com/oauth/authorize ) 로 이동한다
3. 사용자가 로그인 성공을 한경우 (동의하기 버튼 누른 직후)
카카오 서버가 client 에게 너는 로그인을 성공했으니 code를 들고 localhost:8080/login/~/kakao 로 점프하라는 의미로 localhost:8080/login/~/kakao?code=zzzzzz_code 로 redirect 하는 response 를 건네준다
4. 사용자는 code 를 들고 우리 서버의 인증 end_point 로 오면 oauth2-client 다음 일들을 대신 수행해준다
5. 유저의 프로필과 이름을 DB에 저장하여 새로 유저로 등록하거나 조회한다
여기서 user entity 가 확인되면 loadUser 메서드에서 반환한 사용자 정보가 Spring security 가 관리하는 context 안 Authenticaton 객체로 접근이 가능하다
7. Authentication 객체가 조회되면 security oauth2 필터 의 successhandler 로 진입
Authenticaton 의 확인을 통해 어느 handler 로 진입할지 판단
8. successhandler 에서 jwt 를 생성한다
jwt 를 사용자에게 줄때 addCookie 를 사용하여 브라우저 쿠키에 저장하여주고 localhost:8080/ root 페이지로 이동하게끔 redirect 를 걸어준다.
AbstractAuthenticationTargetUrlRequestHandler 에서 제공되는 DefaultRedirectStrategy.class 가 redirect 를 제공해준다
AbstractAuthenticationTargetUrlRequestHandler 안에는 DefaultRedirectStrategy.class 가 제공됨
DefaultRedirectStrategy.class 에서 사용하는 response.encodeRedirectURL 부분이 우리의 기존 설정과 다른점인것같음
정확하게 왜 기존 방식의 handler 는 안됬는지는 모르겠다..
참고문헌 https://godekdls.github.io/Spring%20Security/authentication/