Spring Boot WebFlux GraphQL项目OPTIONS预检请求遭HTTP 403拒绝问题解决咨询
解决WebFlux + GraphQL的OPTIONS预检请求403问题
刚帮几个同事踩过类似的坑,给你几个针对性的解决方案,都是实际验证有效的:
为什么原来的@CrossOrigin失效了?
首先得搞清楚根源:你之前用的@RequestMapping属于Spring WebMvc/WebFlux的基础请求映射,@CrossOrigin注解能直接关联到这些映射生成CORS处理逻辑。但@MutationMapping/@QueryMapping是GraphQL专属的注解,它们并不会触发Spring原生的@CrossOrigin逻辑——因为所有GraphQL请求最终都走统一的端点(默认是/graphql),和你写的映射方法没有直接绑定,所以单独加@CrossOrigin根本不会生效。
方案1:全局WebFlux CORS配置(最推荐)
直接针对GraphQL的端点做全局CORS配置,覆盖所有请求包括OPTIONS预检。写一个配置类即可:
import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.config.CorsRegistry; import org.springframework.web.reactive.config.WebFluxConfigurer; @Configuration public class GlobalCorsConfig implements WebFluxConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/graphql") // 这里填你的GraphQL端点路径,默认是/graphql .allowedOrigins("https://your-frontend-domain.com") // 替换成你的前端域名,生产环境别用* .allowedMethods("GET", "POST", "OPTIONS") // 必须显式包含OPTIONS .allowedHeaders("*") .allowCredentials(true) // 如果前端需要带Cookie/凭证,一定要开这个 .maxAge(3600); // 预检请求的缓存时间,减少重复OPTIONS请求 } }
方案2:通过配置文件直接配置GraphQL端点的CORS
如果你不想写代码,也可以直接在application.yml或application.properties里配置,Spring GraphQL的自动配置会帮你处理:
spring: graphql: cors: allowed-origins: "https://your-frontend-domain.com" allowed-methods: "GET,POST,OPTIONS" allowed-headers: "*" allow-credentials: true max-age: 3600
你之前尝试的GraphQlWebFluxAutoConfiguration.GraphQlEndpointCorsConfiguration其实就是对应这个配置项,可能是因为没写对属性名导致不生效。
方案3:如果用了Spring Security,别忘了放行OPTIONS请求
如果你的项目里有Spring Security,它会优先拦截所有请求,包括OPTIONS预检。这时候需要在安全配置里单独放行/graphql的OPTIONS请求:
import org.springframework.context.annotation.Bean; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { return http .csrf(csrf -> csrf.disable()) // GraphQL用POST的话,通常需要关闭CSRF,或者配置CSRF令牌传递 .authorizeExchange(exchanges -> exchanges .pathMatchers(HttpMethod.OPTIONS, "/graphql").permitAll() // 放行OPTIONS预检 .anyExchange().authenticated() // 其他请求正常校验 ) .build(); }
小提示
- 生产环境尽量不要用
*允许所有Origin,指定具体的前端域名更安全 - 确认你的GraphQL端点路径是否和配置里的一致(比如如果自定义了路径,要同步修改配置中的
/graphql) - 测试的时候可以用浏览器控制台的网络面板,看OPTIONS请求的响应头里有没有
Access-Control-Allow-Origin等CORS相关头,来验证配置是否生效
内容的提问来源于stack exchange,提问作者alexic0n_
相关产品推荐
相关产品推荐

