본문 바로가기
개인적 정리

Spring Security - OAuth2UserService

by 설이주인 2022. 7. 10.
package com.lemint.book.springboot.config.auth;

@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements 
				OAuth2UserService<OAuth2UserRequest, OAuth2User>{

  private final UserRepository userRepository;
  private final HttpSession httpSession;

  @Override
  public OAuth2User loadUser(OAuth2UserRequest userRequest) {
    OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = 
    				new DefaultOAuth2UserService();

    OAuth2User oAuth2User = delegate.loadUser(userRequest);
    /**
     * registrationId :
     * 현재 로그인 진행중인 서비스를 구분하는 코드
     * */
    String registrationId = userRequest.getClientRegistration().getRegistrationId();
    /**
     * userNameAttributeName :
     * OAuth2 로그인 진행 시 키가 되는 필드값. Primary Key 같은 존재
     * */
    String userNameAttributeName = userRequest.getClientRegistration()
    	.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();

    /**
     * OAuthAttributes :
     *  OAuth2UserService를 통해서 가져온  OAuth2User 의  attribute를 담을 클래스
     * */
    OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName, oAuth2User.getAttributes());

    User user = saveOrUpdate(attributes);

    /**
     * SessionUser :
     * 세션에 사용자 정보를 저장하기 위한 Dto 클래스
     * */
    httpSession.setAttribute("user", new SessionUser(user));

    return new DefaultOAuth2User(Collections.singleton(new SimpleGrantedAuthority(user.getRoleKey())),
        attributes.getAttributes(),
        attributes.getNameAttributeKey());
  }

  private User saveOrUpdate(OAuthAttributes attributes) {
    User user = userRepository.findByEmail(attributes.getEmail())
        .map(entity -> entity.update(attributes.getName(), attributes.getPicture()))
        .orElse(attributes.toEntity());

    return userRepository.save(user);
  }
}

 

 

httpSession.setAttribute("user", new SessionUser(user));

위에서 왜  new SessionUser(user) 기존 유저(User) 클래스가 아닌 new SessionUser을 사용하는가?

 

-> 에러 발생 :

직렬화를 구현하지 않았다 -> 그럼 직렬화 코드를 넣는다?

NO -> User 클래스가 엔티티이기 때문이다.

 

엔티티는 수많은 연관 관계가 만들어 질 수 있기에 만약에 관계가 생기면 성능 이슈와 부수 효과가 발생 할 확률이 높다.

그래서 우리는 따로 직렬화 기능을 가진 세션 DTO를 하나 추가로 만드는게 운영, 유지보수에 좋다.