SpringbootSecurity

SpringbootSecurity/Springboot로 구글로그인 해보기(3)/Authentication객체가 가질 수 있는 2가지 타입

25G 2021. 8. 29. 11:59

위 받은 정보들을 분석해 보면

registrationId로 어떤 OAuth로 로그인했는지 확인이 가능하다.

 

Authentication객체 테스트

 

Authentication 를 DI(의존성 주입) 하면 Authentication객체안에 principal이 있고 이 객체는 return타입은 Object이기 때문에 user정보를 다운 캐스팅해서 호출을 하면 user의 정보를 볼 수 있다.

@AuthenticationPrincipal을 통해서 세션정보에 접근할 수 있다. 즉 userDetails에 접근을 할 수 있게 된다는 얘기이다. 하지만 UserDetails타입을 가지고 있다 그렇기 때문에 아래와 같이 수정하면 user오브젝트를 받을 수 있게 된다.

그럼 이번엔 구글로 로그인하면 어떻게 되는지 확인해 보자. 구글 로그인을 하려면 타입을 맞춰줘야 하기 때문에

아래와 같은 test컨트롤러를 하나 더 만들었다.

이제 값이 어떻게 나오는지 확인해 보면 전 포스팅에서 봤던 구글의 회원 프로필의 정보가 리턴되는것을 확인할 수 있다.(전 포스팅 참고)loadUser함수가 리턴하는 회원프로필의 정보를 받는 것이다.

 

 

그럼 위와 같이 테스트를 하나 더 해보면

oauth2 User

authentication

이 두 가지의 정보가 똑같은 것을 확인할 수 있다.

그럼 이테스트를 통해서 알 수 있는 것을 정리를 하자면

스프링 시큐리티는 자기만의 시큐리티 세션을 가지고 있다. 원래 서버 자체가 가지고 있는 session영역은 당연히 있는데 이 영역 안에 시큐리티가 관리하는 session이 있는 것이다. 그럼 이 시큐리티가 관리하는 session에 들어갈 수 있는 타입은 Authentication객체밖에 없다. 그럼 이 session정보가 필요할 때마다 DI를 해서 사용하는데. 

이 Authentication안에 들어갈 수 있는 타입이 2가지가 있는데 

userDetails타입

OAuth2 User타입

이 두 가지 타입이 Authentication객체 안에 들어갈 수 있다.

그럼 언제 userDetails타입이 만들어지냐면 일반적인 로그인을 하게 될 때 userDetail타입이 추가되고

구글/페이스북 같은 OAuth로그인을 하게 될 때 OAuth2User타입이 추가된다.

그럼 이렇게 두 가지 타입의 객체에 들어가게 되면 로그인이 됐을 때 필요한 user의 정보를 session에서 꺼내 써야 하는데 불편함이 있다.

어떤 불편함이냐면

하나의 기능을 구현한다고 가정했을 때

일반적인 로그인을 했을 때 session정보를 가져오는 컨트롤러를 만든다면 

OAuth로그인을 했을때 session정보를 가져오기가 너무 복잡해지는 것이다.

session안에 두 가지 타입이 있기 때문에 처리하기가 굉장히 복잡해짐

 

그래서 위 불편함을 해결하기 위한 방법이 뭐냐면

PrincipalDetails 클래스를 만들어서userDetails타입과OAuth2User타입을 PrincipalDetails 클래스를 implements 해서 타입을 일치시켜서 하나의 타입으로 묶으면 된다.

PrincipalDetails는 지금 하고 있는 프로젝트에서 UserDetails를 상속받는 클래스이다

그럼 이 PrincipalDetails는 UserDetails와 같은 타입이니까 Oauth2User를 PrincipalDetails의 자식으로 두면 userDetails타입과 OAuth2 User타입이 일치가 돼서 컨트롤러에서 관리하기 수월해진다. 사용자가 oauth로그인을 하든 일반적인 로그인을하든 하나의 타입으로 묶었기 때문.

이제 Oauth2User가 가지고 있는 함수를 오버 라이딩해야 한다. 이 오버 라이딩된 함수 처리는 다음 포스팅에서 하겠습니다.

 

핵심 정리

Authentication객체는 userDetails타입과 OAuth2 User타입 이 두 가지 타입만 가질 수 있는데 일반적인 로그인은 userDetails타입 oauth로그인(구글, 페이스북) 로그인은 OAuth2User타입을 사용한다.

그래서 타입이 2개이기때문에 user의 session정보를 받아내기가 상당히 까다로운데 이를 해결하기 위해서 하나의 클래스로 타입을 일치 키면 된다. 

 

https://github.com/fj2008/SpringbootSecurity