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错误
查看网络请求详情:
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
支持*
(允许所有源)或逗号分隔的域名列表allowedMethods
和allowedHeaders
同样支持通配符
更灵活的源匹配:
allowedOriginPatterns:
- https://*.example1.com
- https://www.example2.com:[8080,8081]
- https://www.example3.com:[*]
⚠️ 注意:
allowedOriginPatterns
允许在URL任何部分使用*
(包括协议、域名、端口)- 支持用方括号指定多个端口(如
[8080,8081]
) - 不支持正则表达式
4.4 验证配置效果
✅ 成功返回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构建网关服务
- 调试浏览器跨域请求的典型踩坑场景
- 通过
allowedOrigins
和allowedMethods
配置解决CORS问题
所有示例代码可在GitHub获取。