Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth2 Login Issue: Mismatch Between Database username and principal.getName() #2

Closed
krkarma777 opened this issue Mar 1, 2024 · 2 comments · Fixed by #3
Closed
Assignees
Labels
invalid This doesn't seem right

Comments

@krkarma777
Copy link
Owner

Issue Description
During the integration of Naver OAuth2 for login functionality, we encountered an issue where the username stored in the database does not match the username retrieved from principal.getName() after a successful authentication. This inconsistency is causing problems in user identification and authentication flow within our application.

Expected Behavior
After a successful OAuth2 login, the principal.getName() method should return a username that matches the one stored in our database for the authenticated user. This ensures a consistent user experience and allows for seamless integration of OAuth2 authenticated users with our application's existing user management system.

Current Behavior
Currently, after a successful login via Naver OAuth2, the principal.getName() returns a value that does not match the username stored in our database for the corresponding user. This discrepancy leads to authentication errors and affects the overall user experience.

Steps to Reproduce
Implement Naver OAuth2 login as per the standard integration process.
Perform a login using Naver OAuth2.
After successful authentication, attempt to retrieve the username using principal.getName().
Observe that the retrieved username does not match the one stored in the database for the authenticated user.
Possible Solutions
Investigate the mapping of OAuth2 user attributes to ensure the correct attribute is being used as the username.
Review the configuration of the OAuth2 client to confirm if additional settings are required for Naver OAuth2 integration.
Explore customizing the OAuth2UserService to manually map the correct user attribute to the username.
Additional Context
OAuth2 Configuration: [Briefly describe your OAuth2 configuration, focusing on any customizations or specific settings applied for Naver OAuth2.]
Authentication Flow: [Provide a high-level overview of your authentication flow to help with understanding the context.]
We are seeking solutions or suggestions to resolve this mismatch and ensure that the username retrieved through principal.getName() correctly matches the one stored in our database for OAuth2 authenticated users.

image

@krkarma777 krkarma777 self-assigned this Mar 1, 2024
@krkarma777 krkarma777 added bug Something isn't working invalid This doesn't seem right and removed bug Something isn't working labels Mar 1, 2024
@krkarma777 krkarma777 pinned this issue Mar 1, 2024
@krkarma777
Copy link
Owner Author

 public User getCurrentUser(Principal principal) {
        log.info("principle= [{}]", principal);
        log.info("principal.getName()= [{}]", principal.getName());

        return userService.findByUsername(principal.getName())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자를 찾을 수 없습니다."));
    }
@Service
@RequiredArgsConstructor
public class CustomOAuth2UserService extends DefaultOAuth2UserService {

    private final KakaoLoginService kakaoLoginService;
    private final NaverLoginService naverLoginService;

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {

        OAuth2User user = super.loadUser(userRequest);
        Map<String, Object> attributes = user.getAttributes();

        /* 네이버 로그인 로직 */
        if (attributes.get("message")!=null) {
            String token = naverLoginService.login(attributes);
            return new NaverOAuth2User(user, token);
        }
        /* 카카오 로그인 로직 */
        if (attributes.get("kakao_account") != null) {
            String token = kakaoLoginService.login(attributes);
            return new KakaoOAuth2User(user, token);
        }

        return null;
    }
@Service
@RequiredArgsConstructor
public class NaverLoginService implements SocialOauth2Service{

    private final UserRepository userRepository;
    private final JWTUtil jwtUtil;

    @Value("${jwt.expiredMs}") private String expiredMs;

    @Override
    public String login(Map<String, Object> attributes) {

        // 메시지 상태 확인 후, 성공적으로 정보를 가져왔는지 검증
        if (!"success".equals(attributes.get("message").toString())) {
            throw new OAuth2AuthenticationException("OAuth2 공급자로부터 사용자 정보를 성공적으로 가져오지 못했습니다.");
        }
        // attributes에서 response를 추출하여 사용자 정보 설정
        Map<String, Object> response = (Map<String, Object>) attributes.get("response");

        String email = response.get("email").toString();
        Optional<User> userOpt = userRepository.findByUsername(email);
        String role = "자영업자";
        User userEntity = new User();
        if (userOpt.isEmpty()) {
            userEntity.setUsername(email); // 사용자 고유 이메일을 username으로 사용
            userEntity.setEmail(response.get("email").toString());
            userEntity.setPhoneNumber(response.get("mobile").toString());
            userEntity.setRealName(response.get("name").toString());
            userEntity.setRole(UserRole.ROLE_자영업자); // 모든 사용자를 자영업자로 설정
            userEntity.setPassword(UUID.randomUUID().toString());
            userRepository.save(userEntity);
        } else {
            String gettedRole = userOpt.get().getRole().toString();
            UserRole userRole = UserRole.fromRoleString(gettedRole);
            role = userRole.getDescription();
        }
        return jwtUtil.createJwt(response.get("id").toString(), role, Long.parseLong(expiredMs));
    }
}

@krkarma777 krkarma777 linked a pull request Mar 1, 2024 that will close this issue
@krkarma777
Copy link
Owner Author

This issue has been successfully resolved with the implementation of the user ID as the username for Naver OAuth2 authentication. This approach has addressed the mismatch between the database username and principal.getName(), ensuring consistent user identification throughout the application.
image

krkarma777 added a commit that referenced this issue Mar 2, 2024
fix : #2 Mismatch Between Database username and principal.getName()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant