Spring Gateway整合Swagger调用JWT接口遇CORS错误求助
Spring Gateway整合Swagger调用带JWT接口出现CORS错误
场景说明
- 存在
USER-MANAGER(user服务)和LOGIC-SERVICE(logic服务)两个微服务,通过Spring Gateway统一访问 - 两个服务均配置Spring Security,部分接口需携带JWT令牌才能调用
- logic服务已集成
springdoc-openapi-starter-webmvc-ui,通过@SecurityScheme和@SecurityRequirement标记受保护接口,直接访问微服务自身Swagger可正常调用带令牌接口
问题现象
- 通过Gateway的Swagger可正常切换两个服务的文档,公开接口调用无异常
- 调用带JWT令牌的受保护接口时,已携带正确
Authorization头,却返回CORS错误:
Failed to fetch. Possible Reasons: CORS Network Failure URL scheme must be "http" or "https" for CORS request.
- 将Swagger生成的curl命令中的端口改为Gateway的8080后,调用正常;但Gateway和logic服务Swagger生成的curl默认指向logic服务的8081端口
相关配置信息
Gateway YAML配置
spring: cloud: gateway: default-filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin globalcors: corsConfigurations: '[/**]': allowedOrigins: "*" allowedMethods: "*" allowedHeaders: "*" routes: - id: logic-service uri: lb://LOGIC-SERVICE predicates: - Path=/api/logic/** - id: user-manager uri: lb://USER-MANAGER predicates: - Path=/user-manager/** - Path=/other-api/** - id: logic-service-swagger uri: lb://LOGIC-SERVICE predicates: - Path=/logic/v3/api-docs - id: user-manager-swagger uri: lb://USER-MANAGER predicates: - Path=/user/v3/api-docs springdoc: api-docs: enabled: true swagger-ui: enabled: true path: /swagger-ui.html config-url: /v3/api-docs/swagger-config urls: - url: /logic/v3/api-docs name: Logic service - url: /user/v3/api-docs name: Users service
Gateway依赖
<dependencies> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webflux-ui</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
logic服务OpenAPI配置类
@Configuration @SecurityScheme( name = "bearerAuth", type = SecuritySchemeType.HTTP, bearerFormat = "JWT", scheme = "bearer" ) public class OpenApiConfiguration { }
logic服务控制器注解
@CrossOrigin @SecurityRequirement(name = "bearerAuth") public class LogicController { ... }
已尝试的排查动作
- 配置Gateway全局CORS规则,允许所有Origin、Methods、Headers,添加去重响应头过滤器
- 开启Gateway debug日志,未捕获到相关CORS错误记录
- 确认Eureka服务注册正常,Swagger文档路径正确,可正常切换服务
解决方案
1. 修正微服务Swagger文档的访问地址
问题核心:微服务自身生成的OpenAPI文档中,servers字段指向微服务自身端口(如8081),而非Gateway代理路径。通过Gateway的Swagger调用时,请求会直接发向微服务端口,触发跨域。
需在每个微服务中配置springdoc,指定文档使用Gateway的代理前缀:
logic服务配置
springdoc: api-docs: servers: - url: /api/logic description: Gateway proxy address
user服务配置
springdoc: api-docs: servers: - url: /user-manager description: Gateway proxy address
配置后,Gateway聚合的Swagger文档会自动使用代理路径作为接口请求地址,避免直接访问微服务端口。
2. 调整Gateway CORS配置细节
浏览器限制:allowedOrigins: "*"与allowCredentials: true不能同时生效。若需携带凭证(如JWT令牌),需指定具体Origin,或调整配置:
spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "http://localhost:8080" # 替换为前端地址或Gateway地址 allowedMethods: "*" allowedHeaders: "*" allowCredentials: true default-filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST
若无需携带凭证,可保留allowedOrigins: "*",但需移除allowCredentials配置。
3. 移除微服务控制器的@CrossOrigin注解
Gateway已统一处理跨域,微服务自身的@CrossOrigin会导致响应头重复添加CORS字段,引发冲突。直接移除控制器上的@CrossOrigin注解,由Gateway统一管控跨域规则。
4. 验证Gateway路由匹配规则
确认受保护接口的路径能正确匹配Gateway路由,例如logic服务接口路径为/api/logic/xxx时,Gateway的Path=/api/logic/**规则需能正确转发请求。
内容的提问来源于stack exchange,提问作者Arzybek
相关产品推荐
相关产品推荐

