ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OAuth - 구글 로그인(Authentication 객체가 가지는 2가지 타입)
    스프링/스프링 시큐리티 2024. 1. 9. 23:23

    로컬 로그인

     

    IndexController.class

    @Controller
    public class IndexController {
    
        @GetMapping("/test/login")
        public @ResponseBody String testLogin(Authentication authentication) {
            PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
            System.out.println("authentication : " + principalDetails.getUser());
            return "세션 정보 확인하기";
        }
    }

    localhost:8080/test/login이라는 url에 접근하면 authentication 정보를 출력하도록 api를 만들었다.

    이 때, authentication은 반환 타입이 Object이기 때문에 PrincipalDetails로 형변환을 시켜준 다음에 getUser를 출력했다.

     

     

    출력된 결과를 보면 user의 정보가 여기 들어있는 것을 확인할 수 있다.

     

     

    @Data
    public class PrincipalDetails implements UserDetails {
    
        private User user;
        
        public PrincipalDetails(User user) {
            this.user = user;
        }
    .....
    }

    PrincipalDetails는 이전 포스팅에서 UserDetails를 상속받아서 만든 스프링 시큐리티의 user 객체이다.

    (원래는 UserDetails로 형변환을 해야하는데, 여기서 상속받았으니까 PrincipalDetails로 사용 가능한 것이다.)

     

     

     

    @GetMapping("/test/login")
    public @ResponseBody String testLogin(Authentication authentication,
                                          @AuthenticationPrincipal PrincipalDetails PrincipalDetails) {
        PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
        System.out.println("authentication : " + principalDetails.getUser());
        System.out.println("userDetails : " + PrincipalDetails.getUser());
        return "세션 정보 확인하기";
    }

    아니면 @AuthenticationPrincipal이라는 어노테이션을 사용해도 같은 값을 받아올 수 있다.

     

     

     

     

    구글 로그인

     

    @GetMapping("/test/oauth/login")
    public @ResponseBody String testOAuthLogin(Authentication authentication) {
        OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
        System.out.println("authentication : " + oAuth2User.getAttributes());
    
        return "OAuth 세션 정보 확인하기";
    }

    구글 로그인은 OAuth2User로 형변환을 진행해야한다.

     

     

    authentication을 보면 회원 정보가 들어있는데, 위 getAttributes()와 같은거를 확인할 수 있다.

     

    getAttributes는 이전 포스팅에서의 PrincipalOauth2UserService의 loadUser의 반환 값이다.

     

     

    @GetMapping("/test/oauth/login")
    public @ResponseBody String testOAuthLogin(Authentication authentication,
                                               @AuthenticationPrincipal OAuth2User oauth) {
        OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
        System.out.println("authentication : " + oAuth2User.getAttributes());
    
        System.out.println("oauth2User : " + oauth.getAttributes());
    
        return "OAuth 세션 정보 확인하기";
    }

    구글 로그인도 @AuthenticationPrincipal로 접근이 되는데, 타입이 OAuth2User 타입이다.

     

     

     

     

    테스트 url에서는 이렇게 테스트 해봤지만, 실제로 사용할 때에는 2개를 분리해서 컨트롤러의 파라미터에 넣을 수 없다.

     

     

    해결방법

    타입을 하나 만들어서 UserDetails와 OAuth2User를 상속받게 한다.

    새로운 타입은 부모이기 때문에 로컬 로그인, 소셜 로그인 둘 다 가능하다.

     

     

    PrincipalDetails는 UserDetails를 상속받기 때문에 OAuth2User도 상속받게 한다.

     

     

    PrincipalDetails.class

    @Data
    public class PrincipalDetails implements UserDetails, OAuth2User {
    
        private User user;
    
        public PrincipalDetails(User user) {
            this.user = user;
        }
        
    .... (중간 코드 생략)
    
        @Override
        public Map<String, Object> getAttributes() {
            return null;
        }
    
        @Override
        public String getName() {
            return null;
        }
    }

    OAuth2User도 implements를 해준다.

     

    이 때, getAttributes()와 getName()을 오버라이딩 해야한다.

     

    다음 포스팅에서 이것들을 가지고 구글 로그인 및 자동 회원가입을 진행해보겠다.

Designed by Tistory.