[game] Spring Security에서 Principal을 활용한 사용자 인식 문제 해결

myminimin·2023년 10월 16일

toyproject

목록 보기
11/17
post-thumbnail

문제 발생

Spring Security와 OAuth2를 함께 사용하며, 사용자 인증 후 Principal 객체를 통해 사용자의 정보를 가져오려고 했을 때, 일반 로그인과 소셜 로그인 간의 Principal 타입이 달라 문제가 발생

문제 인지

  1. 처음에는 'UserDetails'와 'OAuth2User' 두 가지 타입만 고려하여 구현
  2. 이후 일반 사용자 로그인에서는 정상적으로 작동하지만, 소셜 로그인 사용자에서는 "Unsupported principal type" 오류 메시지와 함께 'IllegalArgumentException'이 발생
  3. 디버깅 과정에서 소셜 로그인 사용자의 'Principal' 이 'OAuth2AuthenticationToken' 타입이라는 것을 확인

    System.out.println(principal.getClass().getName()); 을 메서드에 넣어서 넘어오는 Principal 객체가 어떤 타입인 지 확인했음

해결 과정

  1. 기존의 'getMemberFromPrincipal' 메서드에 'OAuth2AuthenticationToken'을 체크하는 로직을 추가 (소셜 로그인 시)
  2. 해당 타입의 경우, 'OAuth2User'를 가져와 이메일 속성을 추출하는 로직을 구현
else if (principal instanceof OAuth2AuthenticationToken) {
            // 소셜 로그인 시 -
            // - 소셜 로그인 서비스를 통해 사용자가 인증될 때 생성되는 토큰입니다.
            // - 이 토큰은 인증된 사용자의 세부 정보를 포함하게 됩니다.
            OAuth2User oauth2User = ((OAuth2AuthenticationToken) principal).getPrincipal();
            // 인증된 사용자의 세부 정보(예: 이름, 이메일, 프로필 사진 등)를 담고 있는 'OAuth2User' 객체를 가져옵니다.
            String email = oauth2User.getAttribute("email");
            // 'OAuth2User' 객체에서 이메일 주소를 추출합니다. 이는 소셜 로그인 제공자가 제공하는 정보 중 하나입니다.
            return memberRepository.findByEmail(email).orElse(null);
            // 해당 이메일로 'Member' 객체를 데이터베이스에서 찾아 반환합니다.
  1. 일반 사용자의 경우 'email' 속성을 'username'으로 사용하고 있었기 때문에, 해당 정보를 기반으로 사용자 정보를 찾아옴
if (principal instanceof UsernamePasswordAuthenticationToken) {
            // 일반 로그인 시 -
            // - 사용자가 이름과 비밀번호로 로그인을 시도할 때 생성되는 토큰입니다.
            // - 인증이 성공하면, 이 토큰은 인증된 사용자의 정보를 포함하게 됩니다.
            // - 여기에서 getName()은 인증된 주체의 식별자(대부분 이메일 또는 ID)를 반환합니다.
            String email = ((UsernamePasswordAuthenticationToken) principal).getName();
            return memberRepository.findByEmail(email).orElse(null);

0개의 댓글