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

Spring Boot中Google OAuth登录后重定向及DefaultOAuth2User传递问题

问题解决方案

核心问题分析

  1. 无状态会话导致用户信息丢失:你设置了SessionCreationPolicy.STATELESS,Spring Security不会保存认证会话,重定向后无法通过上下文获取OAuth2用户信息。
  2. 请求方式不匹配:defaultSuccessUrl默认发起GET重定向,但目标接口是@PostMapping,请求方式冲突。
  3. 参数注入方式错误:Spring MVC不会自动将DefaultOAuth2User绑定到接口参数,需通过安全上下文获取认证信息。

具体解决步骤

1. 调整会话策略

若要保留无状态架构,可通过JWT令牌传递用户信息;若允许临时会话,修改Spring Security配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .cors()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 仅在需要时创建会话
            .and()
            .authorizeRequests()
            .antMatchers("/swagger-ui/**", "/swagger-resources/**", "/v2/api-docs")
            .permitAll()
            .anyRequest()
            .permitAll()
            .and()
            .oauth2Login()
            .defaultSuccessUrl("/api/v1/member/oauth")
            .userInfoEndpoint()
            .userService(customOAuth2MemberService);
}

2. 修正接口请求方式

将目标接口改为@GetMapping,匹配重定向的请求类型:

@GetMapping("/api/v1/member/oauth")
public ResponseEntity<DefaultResponseDto> registerOrLogin() {
    // 逻辑实现
}

3. 正确获取OAuth2用户信息

通过SecurityContextHolder获取认证上下文,从中提取用户信息:

@GetMapping("/api/v1/member/oauth")
public ResponseEntity<DefaultResponseDto> registerOrLogin() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    
    // 校验认证信息有效性
    if (authentication == null || !(authentication.getPrincipal() instanceof DefaultOAuth2User)) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(DefaultResponseDto.builder().responseCode("AUTH_FAILED").build());
    }
    
    DefaultOAuth2User oAuth2User = (DefaultOAuth2User) authentication.getPrincipal();
    // 从属性中提取Google用户信息,如邮箱、姓名
    String email = oAuth2User.getAttribute("email");
    String name = oAuth2User.getAttribute("name");
    
    // 执行注册/登录逻辑:检查用户是否存在,不存在则创建,存在则生成登录凭证
    // memberRepository.findByEmail(email)...
    
    return ResponseEntity.ok(
            DefaultResponseDto.builder()
                    .responseCode("MEMBER_LOGIN")
                    .build()
    );
}

4. 验证自定义OAuth2服务(可选)

在CustomOAuth2MemberService中添加日志,确认用户信息是否正确获取:

@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) {
    OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
    OAuth2User oAuth2User;
    try {
        oAuth2User = delegate.loadUser(userRequest);
        System.out.println("获取到的OAuth2用户信息:" + oAuth2User.getAttributes()); // 日志验证
    } catch (OAuth2AuthenticationException e) {
        throw new CustomException(OAUTH_FAIL);
    }
    return new DefaultOAuth2User(oAuth2User.getAuthorities(), oAuth2User.getAttributes(), "sub");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:05:20