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

myminimin·2023년 10월 16일
0

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개의 댓글