You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring OAuth2登录存储问题:Google登录后如何自动保存client-id?

Solution: Automatically Store User Client-ID After Google OAuth Login

The core issue here is that your current storage logic is tied to the /user endpoint, which users might never hit after logging in. To fix this, we need to trigger the client-id storage immediately when a user completes Google OAuth authentication, rather than waiting for them to access a specific API endpoint.

Here's how to implement this step-by-step, using your existing OAuthSecurityConfig.java and adapting the logic from UserRestController.java:

1. Create a Custom OAuth2 Login Success Handler

This handler will run automatically right after a user successfully logs in with Google. We'll move your client-id storage logic here.

@Component
public class GoogleOAuth2LoginSuccessHandler implements AuthenticationSuccessHandler {

    private final UserRepository userRepository; // Inject your existing user repository

    // Constructor injection (Spring will handle this if you're using component scanning)
    public GoogleOAuth2LoginSuccessHandler(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        // Extract OAuth2 user details from the Authentication object
        if (authentication instanceof OAuth2AuthenticationToken oAuth2Token) {
            OAuth2User oAuth2User = oAuth2Token.getPrincipal();
            
            // Fetch the client-id (adjust the attribute key based on what's in your Principal object)
            // For Google OAuth, the unique user ID is typically stored under the "sub" attribute
            String userClientId = oAuth2User.getAttribute("sub");
            
            // Reuse your existing storage logic: check if the user already exists, then save if not
            if (!userRepository.existsByClientId(userClientId)) {
                User newUser = new User();
                newUser.setClientId(userClientId);
                
                // Optional: Add other user details from the OAuth2 attributes
                newUser.setEmail(oAuth2User.getAttribute("email"));
                newUser.setDisplayName(oAuth2User.getAttribute("name"));
                
                userRepository.save(newUser);
            }
        }

        // Redirect the user to your desired post-login page (e.g., homepage)
        response.sendRedirect("/");
    }
}

2. Update OAuthSecurityConfig.java to Use the Custom Handler

Wire up your new success handler in the security configuration so it replaces the default OAuth2 login success behavior:

@Configuration
@EnableWebSecurity
public class OAuthSecurityConfig extends WebSecurityConfigurerAdapter {

    private final GoogleOAuth2LoginSuccessHandler loginSuccessHandler;

    public OAuthSecurityConfig(GoogleOAuth2LoginSuccessHandler loginSuccessHandler) {
        this.loginSuccessHandler = loginSuccessHandler;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .successHandler(loginSuccessHandler); // Attach our custom handler here
    }
}

3. Clean Up UserRestController.java

You can now remove the storage logic from the /user endpoint (since it's no longer needed), or leave it in place as a fallback if you still want to allow manual triggering:

@RestController
@RequestMapping("/user")
public class UserRestController {

    private final UserRepository userRepository;

    public UserRestController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @GetMapping
    public Principal getUser(Principal principal) {
        // Optional: Keep this if you still want to return user details, but remove the storage code
        return principal;
    }
}

Key Notes:

  • Adjust the attribute key: Make sure oAuth2User.getAttribute("sub") matches the actual key for the client-id in your Principal object. If you're referring to the OAuth client's ID (not the user's unique ID), use oAuth2Token.getAuthorizedClientRegistrationId() instead.
  • Avoid duplicate saves: The existsByClientId check ensures you don't create duplicate user records on every login.
  • Post-login redirect: Customize the response.sendRedirect("/") line to send users to whatever page makes sense for your application.

This approach ensures the client-id is stored the moment a user logs in, no matter what they do next—no need to rely on them accessing the /user endpoint.

内容的提问来源于stack exchange,提问作者Gabrielus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:31:07