Spring Boot Filter无法获取自定义请求头问题求助
问题解决:Spring Filter中无法获取自定义请求头userId
核心原因分析
- CORS预检请求干扰:浏览器发送CORS跨域请求时,会先发送
OPTIONS预检请求,这个请求不会携带自定义的userId头,如果你看到的日志是预检请求的,自然找不到该字段;而实际业务请求(GET)会携带,但可能你没区分两种请求的日志。 - Filter执行顺序问题:如果自定义Filter在Spring内置的CORS Filter之前执行,可能在CORS处理完成前无法获取到自定义头。
- 客户端无效头配置:客户端设置了
Access-Control-Allow-Origin(这是服务端响应头,客户端无需设置),可能导致请求头处理异常。
具体解决方案
1. 修正Filter代码,区分请求类型并传递正确请求对象
添加请求方法打印,明确区分预检请求和业务请求,同时确保包装后的请求对象进入过滤链:
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; // 打印请求方法,区分OPTIONS预检和实际业务请求 System.out.println("当前请求方法:" + httpRequest.getMethod()); Enumeration<String> headerNames = httpRequest.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); System.out.println("Header: " + name + " value:" + httpRequest.getHeader(name)); } } // 使用包装后的请求继续执行过滤链 AuthRequestWrapper authRequestWrapper = new AuthRequestWrapper(httpRequest); filterChain.doFilter(authRequestWrapper, servletResponse); }
2. 全局配置CORS,明确允许自定义头
在Spring中配置全局CORS规则,确保userId被允许传递:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:8080") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("Content-Type", "userId") // 明确放行自定义头 .allowCredentials(false); // 匹配客户端的credentials: "omit" } }
如果使用Spring Security,需要在Security配置中同步开启CORS:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors(cors -> cors.configurationSource(corsConfigurationSource())) // 其他安全配置... ; return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://localhost:8080")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("Content-Type", "userId")); configuration.setAllowCredentials(false); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
3. 修正客户端请求代码,移除无效响应头
客户端无需设置Access-Control-Allow-Origin(这是服务端返回给浏览器的响应头),移除后避免请求异常:
let headers: HeadersInit = { "Content-Type": "application/json", "userId":"ABCD" // 仅保留必要的请求头 }
4. 调整Filter执行顺序
确保自定义Filter在Spring CORS Filter之后执行,通过@Order注解指定优先级:
@Component @Order(Ordered.LOWEST_PRECEDENCE - 10) // 内置CORS Filter默认优先级为LOWEST_PRECEDENCE,设置比它高的优先级 public class AuthFilter implements Filter { // Filter实现代码... }
内容的提问来源于stack exchange,提问作者Kaigagi
相关产品推荐
相关产品推荐

