You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway CORS配置失效,跨域请求遭拦截求助

CORS拦截问题:Spring Cloud Gateway + OAuth2资源服务器下预检请求无Access-Control-Allow-Origin头

错误信息

从源'null'访问'http://localhost:8765/conversion/convert'的XMLHttpRequest已被CORS策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在'Access-Control-Allow-Origin'标头。

前端请求代码(jQuery)

$.ajax({
    type: 'POST',
    url: 'http://localhost:8765/conversion/convert',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer MY_JWT_TOKEN'
    },
    data: JSON.stringify({
        id: 1,
        from: 'usd',
        to: 'bdt',
        quantity: 100
    }),
    success: function(data) {
        console.log(data);
    },
    error: function(error) {
        console.error(error);
    }
});

后端依赖版本

  • spring-cloud-gateway: 2022.0.4
  • spring-cloud-starter-gateway: 3.1.6
  • spring-boot-starter-oauth2-resource-server: 3.1.6
  • spring-cloud-starter-netflix-eureka-client

当前网关配置(application.yml)

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-ui: http://localhost:9000/realms/Microservices-demo-realm
          jws-algorithm: RS256
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods: "*"
            allowedHeaders: "*"
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin RETAIN_UNIQUE
        - name: TokenRelay
      routes:
        - id: conversion-service
          uri: lb://currency-conversion
          predicates:
            - Path=/conversion/**

问题现象截图

  • Chrome网络控制台:
    Chrome网络控制台
  • React应用CORS拦截:
    React应用CORS拦截

解决方案

1. 放行OPTIONS预检请求(核心修复)

启用OAuth2资源服务器后,Spring Security会优先拦截请求,OPTIONS预检请求会被安全规则拦截,导致Gateway的CORS逻辑无法执行。需要显式放行OPTIONS请求:

创建Spring Security配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .csrf(ServerHttpSecurity.CsrfSpec::disable)
            .authorizeExchange(exchanges -> exchanges
                // 无条件放行OPTIONS预检请求
                .pathMatchers(org.springframework.http.HttpMethod.OPTIONS).permitAll()
                // 其他请求需认证
                .anyExchange().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> {}));
        return http.build();
    }
}

2. 优化Gateway CORS配置

调整全局CORS配置,补充必要参数并明确规则:

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "*" # 若前端需带凭证,替换为具体域名如"http://localhost:3000"
            allowedMethods: GET, POST, PUT, DELETE, OPTIONS
            allowedHeaders: "*"
            allowCredentials: true # 前端带cookie/凭证时开启
            maxAge: 3600 # 预检请求缓存时长,减少重复请求
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin RETAIN_UNIQUE
        - name: TokenRelay

3. 排查TokenRelay过滤器影响

TokenRelay用于传递OAuth2令牌,但OPTIONS请求不会携带Authorization头,可调整路由过滤器仅在非OPTIONS请求生效:

routes:
  - id: conversion-service
    uri: lb://currency-conversion
    predicates:
      - Path=/conversion/**
    filters:
      - name: TokenRelay
        args:
          enabled: true
      - RemoveRequestHeader=Cookie # 可选,避免传递不必要的Cookie

4. 处理源为'null'的场景

直接打开本地HTML文件(file://协议)会导致源为'null',部分浏览器对allowedOrigins: "*"支持有限。建议将前端部署到HTTP服务器(如http://localhost:8080),并在CORS配置中指定该源:

allowedOrigins: "http://localhost:8080"

5. 验证请求流转

添加日志过滤器确认OPTIONS请求是否到达Gateway:

spring:
  cloud:
    gateway:
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin RETAIN_UNIQUE
        - name: TokenRelay
        - name: RequestLogging
          args:
            includeHeaders: true
            includeQueryString: true
            includePayload: true

查看日志确认OPTIONS请求是否被正确处理,以及响应头是否包含Access-Control-Allow-Origin。

内容的提问来源于stack exchange,提问作者Naim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:11:08