1. 概述

跨域资源共享(CORS)是浏览器应用的安全机制,允许一个域的网页访问另一个域的资源。浏览器通过同源策略限制跨域访问。

Spring官方为所有Spring、Spring Boot和Spring Cloud Gateway应用提供了一流支持,便于配置CORS。

本文将带你:

  • 构建Spring Cloud Gateway服务并对接后端API
  • 通过浏览器调试常见的CORS错误
  • 使用Spring CORS支持解决跨域问题

2. 实现基于Spring Cloud Gateway的API网关

假设我们需要构建一个网关服务来暴露后端REST API。

2.1 实现后端REST API

后端应用提供一个返回用户数据的接口。

首先定义User类:

public class User {
    private long id;
    private String name;

    //标准getter和setter
}

然后实现UserController

@GetMapping(path = "/user/{id}")
public User getUser(@PathVariable("id") long userId) {
    LOGGER.info("Getting user details for user Id {}", userId);
    return userMap.get(userId);
}

2.2 实现Spring Cloud Gateway服务

添加spring-cloud-starter-gateway依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    <version>4.1.5</version>
</dependency>

2.3 配置API路由

通过路由配置暴露用户服务接口:

spring:
  cloud:
    gateway:
      routes:
        - id: user_service_route
          predicates:
            - Path=/user/**
          uri: http://localhost:8081

3. 测试Spring Gateway API

3.1 使用cURL测试网关API

启动两个服务:

$ java -jar ./spring-backend-service/target/spring-backend-service-1.0.0-SNAPSHOT.jar
$ java -jar ./spring-cloud-gateway-service/target/spring-cloud-gateway-service-1.0.0-SNAPSHOT.jar

通过网关访问接口:

$ curl -v 'http://localhost:8080/user/100001'

响应:

< HTTP/1.1 200 OK
< Content-Type: application/json
{"id":100001,"name":"User1"}

✅ 后端API响应正常

3.2 浏览器控制台测试

在浏览器开发者工具中执行跨域请求:

fetch("http://localhost:8080/user/100001")

CORS_ERROR

❌ 典型CORS错误

查看网络请求详情:

OPTIONS /user/100001 HTTP/1.1
Access-Control-Request-Method: GET
Access-Control-Request-Private-Network: true
Connection: keep-alive
Host: localhost:8080
Origin: https://www.baeldung.com

服务器响应:

HTTP/1.1 403 Forbidden
...
content-length: 0

⚠️ 问题根源:

  • 网页域名与网关API不同源
  • 浏览器要求服务器返回Access-Control-Allow-Origin
  • Spring默认对跨域的预检请求返回403

4. 在网关中配置CORS策略

4.1 全局CORS配置

通过globalcors属性配置全局策略:

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "https://www.baeldung.com"
            allowedMethods:
              - GET
            allowedHeaders: "*"

✅ 该配置会应用到所有路由接口

4.2 按路由配置CORS

也可为特定路由配置:

spring:
  cloud:
    gateway:
      routes:
        - id: user_service_route
          # ...其他配置
          metadata:
            cors:
              allowedOrigins: 'https://www.baeldung.com,http://localhost:3000'
              allowedMethods:
                - GET
                - POST
              allowedHeaders: '*'

4.3 高级配置技巧

通配符使用

  • allowedOrigins支持*(允许所有源)或逗号分隔的域名列表
  • allowedMethodsallowedHeaders同样支持通配符

更灵活的源匹配

allowedOriginPatterns:
  - https://*.example1.com
  - https://www.example2.com:[8080,8081]
  - https://www.example3.com:[*]

⚠️ 注意:

  • allowedOriginPatterns允许在URL任何部分使用*(包括协议、域名、端口)
  • 支持用方括号指定多个端口(如[8080,8081]
  • 不支持正则表达式

4.4 验证配置效果

重新测试浏览器请求: CORS_SUCCESS

✅ 成功返回HTTP 200

检查响应头:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://www.baeldung.com
Access-Control-Allow-Methods: GET
content-length: 0

4.5 安全最佳实践

⚠️ 重要提醒:

  • 生产环境应配置具体的允许源列表,避免使用*
  • 默认CORS禁止跨域携带Cookie/CSRF令牌
  • 需要携带凭证时设置allowedCredentials: true
  • allowedCredentials不能与allowedOrigins/allowedHeaders中的*同时使用

5. 总结

本文完整演示了:

  • 使用Spring Cloud Gateway构建网关服务
  • 调试浏览器跨域请求的典型踩坑场景
  • 通过allowedOriginsallowedMethods配置解决CORS问题

所有示例代码可在GitHub获取。


原始标题:Configure CORS Policy for Spring Cloud Gateway | Baeldung