Spring Cloud Gateway+Eureka服务端LB异常:301重定向与401问题
核心问题
你遇到的两次请求、301重定向丢头问题,根源是ABC服务返回了指向自身域名的绝对路径重定向,导致客户端绕过网关直接请求ABC服务,既违背了服务端负载均衡的设计,又丢失了仅发给网关的Authorization头。本地环境正常是因为服务用端口注册,重定向未触发跨域名跳转,客户端仍通过网关转发。
解决方案
1. 修改ABC服务的重定向逻辑(推荐)
让ABC服务返回相对路径重定向(如/test/owned而非https://abc.test.com/test/owned),这样客户端会自动基于当前请求的网关域名(gateway.test.com)发起新请求,所有请求都经过网关,负载均衡和请求头都能正常工作。
如果ABC服务用Spring MVC/Spring Boot实现,可调整重定向代码:
// 错误写法:返回绝对路径 return "redirect:https://abc.test.com/test/owned"; // 正确写法:返回相对路径 return "redirect:/test/owned";
2. 网关层面修改重定向响应头
如果无法修改ABC服务代码,可在Spring Cloud Gateway中添加RewriteLocationResponseHeader过滤器,将重定向地址中的ABC域名替换为网关域名:
- id: ABC uri: lb://ABC predicates: - Path=/test/** filters: # 把Location头中的abc.test.com替换为gateway.test.com - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ^https://abc.test.com, https://gateway.test.com
这个过滤器会自动修改响应中的Location头,让客户端继续请求网关,而非直接访问ABC服务。
3. 配置网关转发X-Forwarded头
确保网关将客户端请求的Host信息转发给ABC服务,让ABC服务基于网关域名生成重定向地址:
spring: cloud: gateway: x-forwarded: enabled: true host-enabled: true
同时在ABC服务中配置使用X-Forwarded-Host生成重定向地址(以Spring Boot为例):
server: forward-headers-strategy: framework
关于负载均衡的说明
虽然你没引入spring-cloud-starter-loadbalancer,但Spring Cloud Gateway在使用lb://协议时,会自动引入负载均衡依赖(属于Spring Cloud Gateway的默认依赖链),这是正常的服务端负载均衡逻辑,不需要额外处理,只要保证请求都经过网关即可。
内容的提问来源于stack exchange,提问作者ECHU

