Spring Boot+Spring Security+OAuth2实现Google登录遇CORS连接失败
解决前后端分离下Spring Security + React Google登录的CORS问题
四天折腾这个确实够累的,我之前在做类似架构项目时也踩过一模一样的坑,给你几个核心的排查和解决方向:
1. 优先检查Spring Security的CORS配置(关键!)
Spring Security的拦截器会优先于普通的Spring Boot CORS配置生效,所以光在@Configuration里加@CrossOrigin或者全局CORS配置可能没用,必须在SecurityFilterChain里明确放行CORS请求:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 先添加CORS配置,一定要放在csrf、authorizeHttpRequests前面 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) // 开发环境可以先禁用,生产再根据情况配置 .authorizeHttpRequests(auth -> auth // 允许Google登录回调相关的请求,以及预检OPTIONS请求 .requestMatchers("/api/auth/google", "/api/auth/google/callback").permitAll() .anyRequest().authenticated() ); return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); // 允许前端的Origin,开发环境可以直接写http://localhost:3000 configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000")); // 允许的请求方法,要包含OPTIONS(预检请求) configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的请求头,包括Google登录可能用到的Authorization、Content-Type等 configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type", "X-Requested-With")); // 如果需要传递cookie或凭证,开启这个(Google登录用token的话可能不需要,但建议开启) configuration.setAllowCredentials(true); // 暴露响应头,方便前端获取自定义头信息 configuration.setExposedHeaders(Arrays.asList("Authorization")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有API路径生效 source.registerCorsConfiguration("/api/**", configuration); return source; } }
2. 前端Google登录请求的注意事项
- 确保你在把Google返回的id_token传给后端时,请求的Origin是http://localhost:3000,不要用相对路径(比如直接写
/api/auth/google),而是完整的http://localhost:8080/api/auth/google - 检查请求头里是否带了
Content-Type: application/json(如果是POST请求),后端要允许这个头 - 不要在请求里随便加自定义头,除非后端已经配置允许
3. 排查浏览器控制台的具体错误
打开浏览器F12的Console和Network面板,看具体的CORS错误信息:
- 如果是
OPTIONS请求返回403,说明Spring Security没放行预检请求,检查上面的SecurityFilterChain配置 - 如果是
Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin,说明后端的AllowedOrigins配置不对,或者没覆盖到对应的路径 - 如果是
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Credentials' header is present on the requested resource,要开启上面配置里的setAllowCredentials(true)
4. 额外的小坑
- 如果你用了Spring Boot的
@CrossOrigin注解,要确保它和全局CORS配置不冲突,建议统一用全局配置 - 开发环境下不要随便用
*作为AllowedOrigins,尤其是当需要允许凭证时,浏览器会拒绝*和allowCredentials: true的组合 - 检查后端是否有其他过滤器(比如自定义的请求过滤器)拦截了OPTIONS请求,要确保这些过滤器也放行OPTIONS请求
先按这个步骤排查,应该能解决大部分问题,毕竟Spring Security的CORS配置是核心痛点,很多人都栽在没把cors()放在SecurityFilterChain的前面。
内容的提问来源于stack exchange,提问作者NastoK
相关产品推荐
相关产品推荐

