Spring Security与CORS请求问题:Authorization头无法传递
解决方案:Spring Boot + React 跨域请求头丢失及CORS错误问题
1. 前端Fetch请求配置修正
Postman能正常请求说明后端接口逻辑没问题,前端Fetch默认不会携带自定义头部(如Authorization)或凭证,需显式配置:
fetch('http://localhost:8080/api/your-target-endpoint', { method: 'GET', // 或POST/PUT/DELETE headers: { 'Authorization': 'Bearer ' + yourAuthToken, 'Content-Type': 'application/json' }, credentials: 'include', // 关键:允许携带凭证(对应后端allowCredentials配置) mode: 'cors' // 明确指定跨域模式,默认虽为cors但显式声明更稳妥 })
2. 后端Spring Security CORS优先级配置
Spring Security过滤器链优先级高于普通@CrossOrigin或自定义CorsFilter,必须在Security配置中统一处理CORS,避免配置冲突:
@Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 优先配置CORS,覆盖全局过滤器 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) // 前后端分离场景通常关闭CSRF,如需开启需配合前端传递CSRF令牌 .authorizeHttpRequests(auth -> auth .requestMatchers("/api/public/**").permitAll() .anyRequest().authenticated() ) // 确保你的AuthTokenFilter在UsernamePasswordAuthenticationFilter之前执行 .addFilterBefore(authTokenFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); // 指定允许的前端域名,不要用*(会和allowCredentials冲突) config.setAllowedOrigins(List.of("http://localhost:3000")); // 允许所有HTTP方法,或按需指定 config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 显式允许自定义头部,包括Authorization config.setAllowedHeaders(List.of("Authorization", "Content-Type", "Accept")); // 允许携带凭证,和前端credentials: 'include'对应 config.setAllowCredentials(true); // 预检请求缓存时长,减少OPTIONS请求次数 config.setMaxAge(3600L); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有接口路径生效 source.registerCorsConfiguration("/**", config); return source; } @Bean public AuthTokenFilter authTokenFilter() { return new AuthTokenFilter(); } }
3. 检查AuthTokenFilter实现
确保过滤器正确从请求头获取值,注意Authorization头的格式(通常为Bearer {token}):
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String headerAuth = request.getHeader("Authorization"); // 先判断头是否存在且符合Bearer格式 if (headerAuth != null && headerAuth.startsWith("Bearer ")) { String token = headerAuth.substring(7); // 后续令牌验证逻辑 } // 务必继续执行过滤器链 filterChain.doFilter(request, response); }
4. 清理冗余配置
移除@CrossOrigin注解、WebConfiguration中的自定义CorsFilter,避免多配置冲突,仅保留Spring Security中的CORS配置即可。
5. 排查浏览器错误详情
打开浏览器控制台,查看CORS错误的具体提示(如Access-Control-Allow-Credentials缺失、自定义头部未被允许等),根据提示精准调整后端配置。
内容的提问来源于stack exchange,提问作者Lucas Soltz
相关产品推荐
相关产品推荐

