Spring Boot中Google OAuth登录后重定向及DefaultOAuth2User传递问题
问题解决方案
核心问题分析
- 无状态会话导致用户信息丢失:你设置了
SessionCreationPolicy.STATELESS,Spring Security不会保存认证会话,重定向后无法通过上下文获取OAuth2用户信息。 - 请求方式不匹配:
defaultSuccessUrl默认发起GET重定向,但目标接口是@PostMapping,请求方式冲突。 - 参数注入方式错误: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
相关产品推荐
相关产品推荐

