gateway的基础应用
2025-06-06 23:37:17 0 举报
AI智能生成
gateway的基础应用
作者其他创作
大纲/内容
认识Gateway
定义
Spring Cloud Gateway 提供了一个构建于 Spring 生态系统之上的 API 网关,其基础包括:Spring 6、Spring Boot 3 和 Project Reactor。旨在提供一种简单而有效的方式来路由到 API,并为它们提供切面(cross-cutting concerns)功能,例如:安全性、监控/指标和弹性(resiliency)。
版本
4.3.0
构建基础
Spring 6、Spring Boot 3 和 Project Reactor
基础功能
统一入口
实现业务集群服务的统一访问地址http(s)://gatewayServer:port/
请求路由
将gateway注册到nacos的注册中心,网关就可以获取所有注册到nacos的服务,通过对routes的配置,可以实现不同服务的路由转发
负载均衡
默认使用Ribbon,自动通过负载均衡算法选择目标实例
可以通过继承LoadBalancerClientFilter,并重写choose方法
通过注解@ConditionalOnProperty实现按配置的方式实现不同的负载均衡策略
流量控制
通过集成sentinel,实现对网关的每个请求实现流量控制,做到全局限制
身份认证
可以实现身份认证功能,例如通过jwt实现token的生成,然后通过在全局过滤器中,增加限制,达到所有请求的授权访问的目的
协议转换
在请求过滤时,可以实现协议的转换,例如从http请求拿到请求数据,然后根据请求数据,再选择性的转发到其他类型的协议,比如dubbo
系统监控
因为所有请求都需要通过路由,因此可以记录请求的访问总量、请求起止时间、慢请求连接等
安全防护
可以对所有请求做XSS(跨站请求攻击)、SQL注入、跨域等防护措施
核心概念
路由 (Route)
网关的基本构建块,他由一个ID、一个目标 URI (destination URI)、一组断言 (Predicates)、一组过滤器 (Filters)组成
当一组聚合断言 (aggregate predicate) 的计算结果为 true 时,该路由即被匹配。
断言 (Predicate)
这是一个 Java 8 Function Predicate。其输入类型是 Spring Framework 的 ServerWebExchange 对象。
断言允许您根据 HTTP 请求中的任何信息进行匹配,例如请求头 (headers) 或参数 (parameters)。
过滤器 (Filter)
实现GatewayFilter的工厂方法,本身提供好多过滤器,自己也可以自定义过滤器。
过滤器允许您在发送下游请求之前或之后修改请求 (requests) 和响应 (responses)。
工作流程
接收请求
客户端 (Clients) 向 Spring Cloud Gateway 发出请求
匹配路由规则
如果 网关处理器映射 (Gateway Handler Mapping) 确定请求匹配 (matches) 某个路由 (Route),则该请求会被发送到 网关 Web 处理器 (Gateway Web Handler)。
应用过滤器链
网关 Web 处理器 (Gateway Web Handler)将请求通过一个特定于该请求的过滤器链 (filter chain that is specific to the request) 运行
过滤器可以在代理请求 (proxy request) 被发送之前 (before) 和之后 (after) 运行逻辑
Pre-Filter(前置过滤):在Gateway Web Handler调用前顺序执行(图中上层Filter)
Post-Filter(后置过滤):在收到Proxied Service响应后逆序执行(图中下层Filter)
⚠️ 注意:全局过滤器(GlobalFilter)通过@Order注解控制优先级,数值越小越早执行。
转发请求至目标服务
NettyRoutingFilter负责最终请求转发
返回响应
路由断言工厂
Route Predicate Factories
Route Predicate Factories
After 路由断言工厂
The After Route Predicate Factory
After 路由断言工厂接受一个参数:一个日期时间(Java ZonedDateTime 类型)。此断言匹配发生在指定日期时间之后的请求。
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
Before 路由断言工厂
The Before Route Predicate Factory
Before 路由断言工厂接受一个参数:一个日期时间(Java ZonedDateTime 类型)。此断言匹配发生在指定日期时间之前的请求。
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
Between 路由断言工厂
The Between Route Predicate Factory
Between 路由断言工厂接受两个参数:datetime1 和 datetime2,它们都是 Java ZonedDateTime 对象。
此断言匹配发生在 datetime1 之后且在 datetime2 之前的请求。datetime2 参数必须在 datetime1 之后。
此断言匹配发生在 datetime1 之后且在 datetime2 之前的请求。datetime2 参数必须在 datetime1 之后。
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
Cookie 路由断言工厂
The Cookie Route Predicate Factory
Cookie 路由断言工厂接受两个参数:Cookie 名称和一个正则表达式(Java 正则表达式)。此断言匹配具有给定名称且其值匹配正则表达式的 Cookie。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
Header 路由断言工厂
The Header Route Predicate Factory
Header 路由断言工厂接受两个参数:Header 名称和一个正则表达式(Java 正则表达式)。此断言匹配具有给定名称且其值匹配正则表达式的 Header。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
Host 路由断言工厂
The Host Route Predicate Factory
Host 路由断言工厂接受一个参数:主机名模式列表。
模式是以 . 作为分隔符的 Ant 风格模式。
此断言匹配与模式匹配的 Host Header。
模式是以 . 作为分隔符的 Ant 风格模式。
此断言匹配与模式匹配的 Host Header。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
Method 路由断言工厂
The Method Route Predicate Factory
Method 路由断言工厂接受一个 methods 参数,该参数是一个或多个 HTTP 方法(例如 GET, POST)。
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
Path 路由断言工厂
The Path Route Predicate Factory
Path 路由断言工厂接受两个参数:一个 Spring PathMatcher 模式列表和一个名为 matchTrailingSlash 的可选标志(默认为 true)。
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
Query 路由断言工厂
The Query Route Predicate Factory
Query 路由断言工厂接受两个参数:一个必需的 param(参数名)和一个可选的 regexp(Java 正则表达式)。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
RemoteAddr 路由断言工厂
The RemoteAddr Route Predicate Factory
RemoteAddr 路由断言工厂接受一个源列表(最小大小为 1),这些源是 CIDR 表示法(IPv4 或 IPv6)的字符串,例如 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子网掩码)。
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
Weight 路由断言工厂
The Weight Route Predicate Factory
Weight 路由断言工厂接受两个参数:group(组名)和 weight(权重,整数)。权重按组计算。
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
XForwarded Remote Addr 路由断言工厂
The XForwarded Remote Addr Route Predicate Factory
此路由断言允许根据 X-Forwarded-For HTTP Header 过滤请求。这可以与反向代理(如负载均衡器或 Web 应用程序防火墙)一起使用,其中请求应仅当它来自这些反向代理使用的受信任 IP 地址列表时才被允许。
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
网关过滤器工厂
GatewayFilter Factories
GatewayFilter Factories
AddRequestHeader:
添加请求头网关过滤器工厂
添加请求头网关过滤器工厂
接收 name(名称)和 value(值)参数
示例1:
添加请求头X-Request-red 值是blue
添加请求头X-Request-red 值是blue
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
示例2:
添加请求头X-Request-red 值是Blue加上主机的 URI 变量
添加请求头X-Request-red 值是Blue加上主机的 URI 变量
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
AddRequestHeadersIfNotPresent:
添加请求头(如不存在)网关过滤器工厂
添加请求头(如不存在)网关过滤器工厂
接收一个以冒号分隔的名称-值对集合
仅在头部尚不存在时才会添加。否则,将发送客户端请求中的原始值。
示例1
向下游请求的头部添加 两个头部
向下游请求的头部添加 两个头部
spring:
cloud:
gateway:
routes:
- id: add_request_headers_route
uri: https://example.org
filters:
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
cloud:
gateway:
routes:
- id: add_request_headers_route
uri: https://example.org
filters:
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
示例2
匹配路径或主机的 URI 变量
匹配路径或主机的 URI 变量
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
AddRequestParameter:
添加请求参数网关过滤器工厂
添加请求参数网关过滤器工厂
接收 name(名称)和 value(值)参数
为所有匹配的请求,向下游请求的查询字符串添加 name=value
示例1
向下游请求的查询字符串添加 red=blue
向下游请求的查询字符串添加 red=blue
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
示例2
识别用于匹配路径或主机的 URI 变量。
URI 变量可以在 value 中使用,并在运行时展开
识别用于匹配路径或主机的 URI 变量。
URI 变量可以在 value 中使用,并在运行时展开
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
AddResponseHeader:
添加响应头网关过滤器工厂
添加响应头网关过滤器工厂
接收 name(名称)和 value(值)参数
为所有匹配的请求,向下游响应的头部添加 name:value头
示例1:
向下游响应的头部添加 X-Response-Red:Blue 头
向下游响应的头部添加 X-Response-Red:Blue 头
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
示例2:
URI 变量可以在 value 中使用,并在运行时展开
URI 变量可以在 value 中使用,并在运行时展开
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
CircuitBreaker:
断路器网关过滤器工厂
断路器网关过滤器工厂
默认支持 Resilience4J
在类路径中包含 spring-cloud-starter-circuitbreaker-reactor-resilience4j
示例1
简单
简单
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
示例2
接受一个可选的 fallbackUri 参数
触发了回退 (fallback),请求将被转发到该 URI 匹配的控制器
接受一个可选的 fallbackUri 参数
触发了回退 (fallback),请求将被转发到该 URI 匹配的控制器
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088 # 使用负载均衡
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis # 回退到网关内的端点
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint # 可选路径重写
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088 # 使用负载均衡
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis # 回退到网关内的端点
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint # 可选路径重写
CacheRequestBody:
缓存请求体网关过滤器工厂
缓存请求体网关过滤器工厂
由于请求体只能读取一次,我们需要缓存请求体
示例:
将请求体转换为指定的 body 类(例子:java.lang.String)。
然后,CacheRequestBody 将其放入 ServerWebExchange.getAttributes() 可用的属性中,键由 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定义
将请求体转换为指定的 body 类(例子:java.lang.String)。
然后,CacheRequestBody 将其放入 ServerWebExchange.getAttributes() 可用的属性中,键由 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定义
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("cache_request_body_route", r -> r.path("/downstream/**")
.filters(f -> f.prefixPath("/httpbin")
.cacheRequestBody(String.class).uri(uri))
.build();
}
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("cache_request_body_route", r -> r.path("/downstream/**")
.filters(f -> f.prefixPath("/httpbin")
.cacheRequestBody(String.class).uri(uri))
.build();
}
spring:
cloud:
gateway:
routes:
- id: cache_request_body_route
uri: lb://downstream
predicates:
- Path=/downstream/**
filters:
- name: CacheRequestBody
args:
bodyClass: java.lang.String # 请求体转换的目标类
cloud:
gateway:
routes:
- id: cache_request_body_route
uri: lb://downstream
predicates:
- Path=/downstream/**
filters:
- name: CacheRequestBody
args:
bodyClass: java.lang.String # 请求体转换的目标类
DedupeResponseHeader:
重复响应头网关过滤器工厂 /
响应头去重网关过滤器工厂
重复响应头网关过滤器工厂 /
响应头去重网关过滤器工厂
接收一个 name(名称)参数和一个可选的 strategy(策略)参数。name 可以包含一个以空格分隔的头部名称列表
示例:
在网关的 CORS 逻辑和下游逻辑都添加了 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 响应头的情况下,此过滤器会移除它们的重复值。
在网关的 CORS 逻辑和下游逻辑都添加了 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 响应头的情况下,此过滤器会移除它们的重复值。
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
可选的 strategy 参数
RETAIN_FIRST:保留第一个值(默认)
RETAIN_LAST:保留最后一个值
RETAIN_UNIQUE:保留所有唯一值(按首次出现的顺序)
FallbackHeaders:
后备(降级)头网关过滤器工厂
后备(降级)头网关过滤器工厂
允许您在转发到外部应用程序的 fallbackUri 的请求头中添加 CircuitBreaker 执行异常的详细信息
示例
当运行断路器期间发生执行异常时,请求被转发到运行在 localhost:9994 上的应用程序中的回退端点或处理器
当运行断路器期间发生执行异常时,请求被转发到运行在 localhost:9994 上的应用程序中的回退端点或处理器
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders # 添加异常信息到请求头
args:
executionExceptionTypeHeaderName: Test-Header # 自定义头名称 (可选)
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders # 添加异常信息到请求头
args:
executionExceptionTypeHeaderName: Test-Header # 自定义头名称 (可选)
过滤器将包含异常类型、消息以及(如果可用)根本原因异常类型和消息的头部添加到该请求中
executionExceptionTypeHeaderName ("Execution-Exception-Type")
executionExceptionMessageHeaderName ("Execution-Exception-Message")
rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")
JsonToGrpc:
JSON转Grpc网关过滤器工厂
JSON转Grpc网关过滤器工厂
将 JSON 负载转换为 gRPC 请求
参数
protoDescriptor: Proto 描述符文件 (.pb 文件)。
可以使用 protoc 并指定 --descriptor_set_out 标志生成此文件:
protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb \
src/main/resources/proto/hello.proto
--descriptor_set_out=src/main/resources/proto/hello.pb \
src/main/resources/proto/hello.proto
protoFile: Proto 定义文件 (.proto 文件)。
service: 处理请求的服务的简称。
method: 服务中处理请求的方法名。
不支持流式传输 (streaming is not supported)。
例子
当通过网关向 /json/hello 发出请求时,
请求将使用 hello.proto 中提供的定义进行转换,
发送到 HelloService/hello,
然后将响应转换回 JSON。
当通过网关向 /json/hello 发出请求时,
请求将使用 hello.proto 中提供的定义进行转换,
发送到 HelloService/hello,
然后将响应转换回 JSON。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("json-grpc", r -> r.path("/json/hello").filters(f -> {
String protoDescriptor = "file:src/main/proto/hello.pb";
String protoFile = "file:src/main/proto/hello.proto";
String service = "HelloService";
String method = "hello";
return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
}).uri(uri))
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("json-grpc", r -> r.path("/json/hello").filters(f -> {
String protoDescriptor = "file:src/main/proto/hello.pb";
String protoFile = "file:src/main/proto/hello.proto";
String service = "HelloService";
String method = "hello";
return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
}).uri(uri))
spring:
cloud:
gateway:
routes:
- id: json-grpc
uri: https://localhost:6565/testhello
predicates:
- Path=/json/**
filters:
- name: JsonToGrpc
args:
protoDescriptor: file:proto/hello.pb
protoFile: file:proto/hello.proto
service: HelloService
method: hello
cloud:
gateway:
routes:
- id: json-grpc
uri: https://localhost:6565/testhello
predicates:
- Path=/json/**
filters:
- name: JsonToGrpc
args:
protoDescriptor: file:proto/hello.pb
protoFile: file:proto/hello.proto
service: HelloService
method: hello
LocalResponseCache:
本地响应缓存网关过滤器工厂
本地响应缓存网关过滤器工厂
允许缓存响应体和头部
规则
只能缓存无请求体 (bodiless) 的 GET 请求。
仅缓存以下状态码之一的响应:HTTP 200 (OK)、HTTP 206 (Partial Content) 或 HTTP 301 (Moved Permanently)
如果 Cache-Control 头部不允许缓存(请求中存在 no-store 或响应中存在 no-store 或 private),则不会缓存响应数据。
如果响应已被缓存,并且使用 Cache-Control 头部值为 no-cache 的新请求执行,它将返回一个无响应体的 304 (Not Modified) 响应。
仅在 spring.cloud.gateway.filter.local-response-cache.enabled 属性启用时才可用
参数
第一个参数来覆盖缓存条目的过期时间(以 s 表示秒,m 表示分钟,h 表示小时)
第二个参数设置此路由缓存的最大大小(KB、MB 或 GB)
例子
# 缓存30分钟,最大500MB
# 缓存30分钟,最大500MB
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.localResponseCache(Duration.ofMinutes(30), "500MB") // 缓存30分钟,最大500MB
).uri(uri))
.build();
}
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.localResponseCache(Duration.ofMinutes(30), "500MB") // 缓存30分钟,最大500MB
).uri(uri))
.build();
}
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- LocalResponseCache=30m,500MB # 缓存30分钟,最大500MB
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- LocalResponseCache=30m,500MB # 缓存30分钟,最大500MB
MapRequestHeader:
映射请求头网关过滤器工厂
映射请求头网关过滤器工厂
接收 fromHeader 和 toHeader 参数
创建一个新的命名头部 (toHeader),其值是从传入 HTTP 请求的现有命名头部 (fromHeader) 中提取出来
如果输入头部不存在,则此过滤器不起作用。如果新的命名头部已存在,则其值将用新值进行扩充
例子
向下游请求添加 X-Request-Red:<values> 头部,
其值是从传入 HTTP 请求的 Blue 头部更新而来
向下游请求添加 X-Request-Red:<values> 头部,
其值是从传入 HTTP 请求的 Blue 头部更新而来
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
ModifyRequestBody:
修改请求体网关过滤器工厂
修改请求体网关过滤器工厂
在请求体被网关发送到下游之前修改它
此过滤器只能使用 Java DSL 配置。
示例
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> Mono.just(new Hello(s.toUpperCase())))).uri(uri)) // 转换逻辑
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> Mono.just(new Hello(s.toUpperCase())))).uri(uri)) // 转换逻辑
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
如果请求没有请求体,RewriteFilter 会接收到 null。
应返回 Mono.empty() 以在请求中分配一个缺失的请求体。
应返回 Mono.empty() 以在请求中分配一个缺失的请求体。
ModifyResponseBody:
修改响应体网关过滤器工厂
修改响应体网关过滤器工厂
在响应体被发送回客户端之前修改它
此过滤器只能使用 Java DSL 配置。
示例
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)) // 转换逻辑 (转大写)
.build();
}
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)) // 转换逻辑 (转大写)
.build();
}
如果响应没有响应体,RewriteFilter 会接收到 null。应返回 Mono.empty() 以在响应中分配一个缺失的响应体。
PrefixPath:
路径前缀网关过滤器工厂
路径前缀网关过滤器工厂
接收一个 prefix(前缀)参数
示例
这将在所有匹配请求的路径前添加 /mypath。
对 /hello 的请求将被发送到 /mypath/hello。
这将在所有匹配请求的路径前添加 /mypath。
对 /hello 的请求将被发送到 /mypath/hello。
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
PreserveHostHeader:
保留主机头网关过滤器工厂
保留主机头网关过滤器工厂
没有参数
示例
此过滤器设置一个请求属性,路由过滤器会
检查该属性以确定是否应发送原始 Host 头部,
而不是由 HTTP 客户端确定的 Host 头部。
此过滤器设置一个请求属性,路由过滤器会
检查该属性以确定是否应发送原始 Host 头部,
而不是由 HTTP 客户端确定的 Host 头部。
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
RedirectTo:
重定向至网关过滤器工厂
重定向至网关过滤器工厂
接收三个参数
status 参数:应该是一个 300 系列的重定向 HTTP 状态码,例如 301。
url 参数:应该是一个有效的 URL。这将作为 Location 响应头的值。
includeRequestParams 参数(可选):指示是否应将原始请求的查询参数包含在重定向的 url 中。如果未设置此参数,则默认为 false。
示例
这将发送一个状态码为 302 且带有 Location:https://acme.org 响应头的响应,以执行重定向。
这将发送一个状态码为 302 且带有 Location:https://acme.org 响应头的响应,以执行重定向。
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
示例
当向网关发出带有查询参数 ?skip=10 的请求时,网关将发送一个状态码为 302 且带有 Location:https://acme.org?skip=10 响应头的响应来执行重定向(即原始查询参数 skip=10 被包含在了重定向 URL 中)。
当向网关发出带有查询参数 ?skip=10 的请求时,网关将发送一个状态码为 302 且带有 Location:https://acme.org?skip=10 响应头的响应来执行重定向(即原始查询参数 skip=10 被包含在了重定向 URL 中)。
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org, true
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org, true
RemoveJsonAttributesResponseBody:
移除响应体JSON属性网关过滤器工厂
移除响应体JSON属性网关过滤器工厂
接收一个要搜索的属性名称集合,从 JSON 正文内容中删除属性来对其进行转换
该列表中的最后一个参数可以是可选的布尔值,
用于指定是仅删除根级别的属性(这是参数配置末尾
不提供此选项时的默认值 false),
还是递归删除所有级别的属性(true)
用于指定是仅删除根级别的属性(这是参数配置末尾
不提供此选项时的默认值 false),
还是递归删除所有级别的属性(true)
示例
从 JSON 正文内容的根级别删除属性 "id" 和 "color"
从 JSON 正文内容的根级别删除属性 "id" 和 "color"
spring:
cloud:
gateway:
routes:
- id: removejsonattributes_route
uri: https://example.org
filters:
- RemoveJsonAttributesResponseBody=id,color
cloud:
gateway:
routes:
- id: removejsonattributes_route
uri: https://example.org
filters:
- RemoveJsonAttributesResponseBody=id,color
示例
将从 JSON 正文内容的任何级别(递归地)删除属性 "id" 和 "color"
将从 JSON 正文内容的任何级别(递归地)删除属性 "id" 和 "color"
spring:
cloud:
gateway:
routes:
- id: removejsonattributes_recursively_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- RemoveJsonAttributesResponseBody=id,color,true # 注意结尾的 ",true" 参数
cloud:
gateway:
routes:
- id: removejsonattributes_recursively_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- RemoveJsonAttributesResponseBody=id,color,true # 注意结尾的 ",true" 参数
RemoveRequestHeader:
移除请求头网关过滤器工厂
移除请求头网关过滤器工厂
接收一个 name(名称)参数
被移除的请求头的名称
被移除的请求头的名称
示例
在 X-Request-Foo 请求头被发送到下游服务之前将其移除
在 X-Request-Foo 请求头被发送到下游服务之前将其移除
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route # 路由ID
uri: https://example.org # 目标URI
filters:
- RemoveRequestHeader=X-Request-Foo # 过滤器:移除指定请求头
cloud:
gateway:
routes:
- id: removerequestheader_route # 路由ID
uri: https://example.org # 目标URI
filters:
- RemoveRequestHeader=X-Request-Foo # 过滤器:移除指定请求头
RemoveRequestParameter:
移除请求参数网关过滤器工厂
移除请求参数网关过滤器工厂
接收一个 name(名称)参数
被移除的查询参数的名称
被移除的查询参数的名称
示例
在 red 查询参数被发送到下游服务之前将其移除
在 red 查询参数被发送到下游服务之前将其移除
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route # 路由ID
uri: https://example.org # 目标URI
filters:
- RemoveRequestParameter=red # 过滤器:移除指定查询参数
cloud:
gateway:
routes:
- id: removerequestparameter_route # 路由ID
uri: https://example.org # 目标URI
filters:
- RemoveRequestParameter=red # 过滤器:移除指定查询参数
RemoveResponseHeader:
移除响应头网关过滤器工厂
移除响应头网关过滤器工厂
接收一个 name(名称)参数。
需要被移除的响应头的名称。
需要被移除的响应头的名称。
示例
自下游服务的响应被返回给网关客户端之前,
从该响应中移除 X-Response-Foo 头
自下游服务的响应被返回给网关客户端之前,
从该响应中移除 X-Response-Foo 头
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
filters:
- RemoveResponseHeader=X-Response-Foo # 过滤器:移除指定响应头
cloud:
gateway:
routes:
- id: removeresponseheader_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
filters:
- RemoveResponseHeader=X-Response-Foo # 过滤器:移除指定响应头
为了移除任何类型的敏感响应头
为任何可能需要此操作的路由配置此过滤器。
此外,您还可以使用 spring.cloud.gateway.default-filters 一次性配置此过滤器,使其应用于所有路由。
RequestHeaderSize:
请求头大小网关过滤器工厂
请求头大小网关过滤器工厂
用于限制客户端请求头 (Request Header) 的总大小
目的是防止过大或不合理的请求头导致性能问题或拒绝服务攻击。
接收两个参数
maxSize 参数:请求头(包括键名和键值)所允许的最大数据大小。
errorHeaderName 参数(可选):设置响应头中包含错误消息的头名称。默认值为 "errorMessage"。
示例
如果任何一个请求头的大小超过 1000 字节 (Bytes),
网关将返回 HTTP 状态码 431(请求头字段过大)。
如果任何一个请求头的大小超过 1000 字节 (Bytes),
网关将返回 HTTP 状态码 431(请求头字段过大)。
spring:
cloud:
gateway:
routes:
- id: requestheadersize_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
filters:
- RequestHeaderSize=1000B # 过滤器:设置最大请求头大小为1000字节
cloud:
gateway:
routes:
- id: requestheadersize_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
filters:
- RequestHeaderSize=1000B # 过滤器:设置最大请求头大小为1000字节
RequestRateLimiter:
请求速率限制网关过滤器工厂
请求速率限制网关过滤器工厂
用于限制客户端请求速率,防止下游服务过载。
超过速率的话:返回 HTTP 429 - Too Many Requests (请求过多) 状态码
参数
keyResolver
keyResolver 是一个实现了 KeyResolver 接口的 Bean。在配置中,使用 SpEL 通过名称引用该 Bean。#{@myKeyResolver} 是一个 SpEL 表达式,它引用名为 myKeyResolver 的 Bean。
允许使用可插拔策略来派生用于限制请求的键(Key)
默认实现是 PrincipalNameKeyResolver,它从 ServerWebExchange 中检索 Principal 并调用 Principal.getName()
默认拒绝无法解析出键(Key)的请求
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true 或 false)
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
示例:
先创建bean,然后再配置
RequestRateLimiter 不能使用 "快捷" 表示法配置
只能通过下面配置
先创建bean,然后再配置
RequestRateLimiter 不能使用 "快捷" 表示法配置
只能通过下面配置
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
spring:
cloud:
gateway:
routes:
- id: limit
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@userkeyresolver}" # 引用 KeyResolver Bean
cloud:
gateway:
routes:
- id: limit
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@userkeyresolver}" # 引用 KeyResolver Bean
Redis 速率限制器
Redis RateLimiter
Redis RateLimiter
基于 Stripe 完成的工作。它需要使用
spring-boot-starter-data-redis-reactive
spring-boot-starter-data-redis-reactive
令牌桶算法
Token Bucket Algorithm
Token Bucket Algorithm
redis-rate-limiter.replenishRate 属性:定义您希望每秒允许执行多少请求(不会丢弃任何请求)。这是令牌桶被填充的速率。
redis-rate-limiter.burstCapacity 属性:允许用户在一秒钟内执行的最大请求数(不会丢弃任何请求)。这是令牌桶可以容纳的令牌数。将此值设置为零会阻止所有请求。
redis-rate-limiter.requestedTokens 属性:一个请求消耗多少令牌。这是每个请求从桶中取出的令牌数,默认为 1。
replenishRate 和 burstCapacity 设置为相同的值可以实现稳定的速率。通过将 burstCapacity 设置为高于 replenishRate 可以允许临时突发。低于 1 请求/秒的速率限制可以通过将 replenishRate 设置为所需的请求数,将 requestedTokens 设置为时间跨度(秒),并将 burstCapacity 设置为 replenishRate 和 requestedTokens 的乘积来实现。
示例
此配置定义了每个用户 10 个请求/秒的速率限制。允许突发 20 个请求,但在下一秒,只有 10 个请求可用。上面示例中的 KeyResolver 是一个简单的解析器,它获取 user 请求参数(注意:这不建议用于生产环境)。
此配置定义了每个用户 10 个请求/秒的速率限制。允许突发 20 个请求,但在下一秒,只有 10 个请求可用。上面示例中的 KeyResolver 是一个简单的解析器,它获取 user 请求参数(注意:这不建议用于生产环境)。
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒补充10个令牌
redis-rate-limiter.burstCapacity: 20 # 桶容量为20个令牌 (允许突发)
redis-rate-limiter.requestedTokens: 1 # 每个请求消耗1个令牌
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒补充10个令牌
redis-rate-limiter.burstCapacity: 20 # 桶容量为20个令牌 (允许突发)
redis-rate-limiter.requestedTokens: 1 # 每个请求消耗1个令牌
Bucket4j 速率限制器
Bucket4j RateLimiter
Bucket4j RateLimiter
基于 Bucket4j Java 库。它需要使用 com.bucket4j:bucket4j_jdk17-core 依赖项以及一个分布式持久化选项
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<dependency>
<groupId>com.bucket4j</groupId>
<artifactId>bucket4j_jdk17-caffeine</artifactId>
<version>${bucket4j.version}</version>
</dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<dependency>
<groupId>com.bucket4j</groupId>
<artifactId>bucket4j_jdk17-caffeine</artifactId>
<version>${bucket4j.version}</version>
</dependency>
示例
每个用户 10 个请求/秒的速率限制。允许突发 20 个请求,但在下一秒,只有 10 个请求可用。
注意:示例中的 KeyResolver 不建议用于生产环境
每个用户 10 个请求/秒的速率限制。允许突发 20 个请求,但在下一秒,只有 10 个请求可用。
注意:示例中的 KeyResolver 不建议用于生产环境
首先,需要创建一个类型为 io.github.bucket4j.distributed.proxy.AsyncProxyMananger<String> 的 Bean。
@Bean
AsyncProxyManager<String> caffeineProxyManager() {
Caffeine<String, RemoteBucketState> builder = (Caffeine) Caffeine.newBuilder().maximumSize(100);
return new CaffeineProxyManager<>(builder, Duration.ofMinutes(1)).asAsync();
}
AsyncProxyManager<String> caffeineProxyManager() {
Caffeine<String, RemoteBucketState> builder = (Caffeine) Caffeine.newBuilder().maximumSize(100);
return new CaffeineProxyManager<>(builder, Duration.ofMinutes(1)).asAsync();
}
Bucket4j RateLimiter 配置
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
bucket4j-rate-limiter.capacity: 20 # 桶容量 (允许突发)
bucket4j-rate-limiter.refillTokens: 10 # 每个补充周期添加的令牌数
bucket4j-rate-limiter.refillPeriod: 1s # 补充周期 (1秒)
bucket4j-rate-limiter.requestedTokens: 1 # 每个请求消耗1个令牌
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
bucket4j-rate-limiter.capacity: 20 # 桶容量 (允许突发)
bucket4j-rate-limiter.refillTokens: 10 # 每个补充周期添加的令牌数
bucket4j-rate-limiter.refillPeriod: 1s # 补充周期 (1秒)
bucket4j-rate-limiter.requestedTokens: 1 # 每个请求消耗1个令牌
配置说明
bucket4j-rate-limiter.capacity 属性:允许用户在一秒钟内执行的最大请求数(不会丢弃任何请求)。这是令牌桶可以容纳的令牌数。必须大于零。
bucket4j-rate-limiter.refillPeriod 属性:定义补充周期。桶以 refillTokens 个令牌 / refillPeriod 的速率进行补充。这是一个必需属性,使用 Spring Boot 的 Period 格式(例如 1s, 5m, 1h)。
bucket4j-rate-limiter.refillTokens 属性:定义在 refillPeriod 期间向桶中添加多少令牌。默认为 capacity,且必须大于或等于零。
bucket4j-rate-limiter.requestedTokens 属性:一个请求消耗多少令牌。这是每个请求从桶中取出的令牌数,默认为 1。必须大于零。
bucket4j-rate-limiter.refillStyle 属性:定义桶的补充方式。
GREEDY (默认):尽快将令牌添加到桶中。
INTERVALLY:与贪婪模式相反,等待整个 refillPeriod 过去后才补充令牌。
INTERVALLY_ALIGNED:类似于 INTERVALLY,但使用指定的 timeOfFirstRefill 进行对齐。
bucket4j-rate-limiter.timeOfFirstRefill 属性:一个 Instant 对象,仅当 refillStyle 设置为 INTERVALLY_ALIGNED 时使用。
自定义 RateLimiter
Custom RateLimiter
Custom RateLimiter
您也可以将速率限制器定义为实现 RateLimiter 接口的 Bean。在配置中,您可以使用 SpEL 通过名称引用该 Bean。#{@myRateLimiter} 是一个 SpEL 表达式,它引用名为 myRateLimiter 的 Bean。
示例
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}" # 引用自定义 RateLimiter Bean
key-resolver: "#{@userKeyResolver}" # 引用 KeyResolver Bean
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}" # 引用自定义 RateLimiter Bean
key-resolver: "#{@userKeyResolver}" # 引用 KeyResolver Bean
RewriteLocationResponseHeader:
重写位置响应头网关过滤器工厂
重写位置响应头网关过滤器工厂
修改响应头 Location 的值,通常是为了消除特定于后端的详细信息
当后端服务返回带有 Location 头的响应时(通常是重定向场景),此过滤器用于重写该 Location URL,使其去除后端特定的细节(如内部主机名、版本号),使其成为面向客户端的有效 URL。
参数
Mode
模式
模式
NEVER_STRIP:不剥离版本信息,即使原始请求路径中不包含版本号。
AS_IN_REQUEST(默认):仅当原始请求路径中不包含版本号时才剥离版本信息。
ALWAYS_STRIP:总是剥离版本信息,即使原始请求路径中包含版本号。
ocationHeaderName
位置头名称
位置头名称
hostValue
主机值
主机值
如果提供了该参数,它将用于替换响应 Location 头中的 主机:端口 部分。
如果未提供,则使用请求中的 Host 头部的值。
protocols
协议
协议
必须是一个有效的正则表达式字符串,协议名称需要与该正则表达式匹配。
如果不匹配,则过滤器不做任何操作。
默认值为 https?|ftps?(匹配 http, https, ftp, ftps)。
示例
对于一个请求 POST api.example.com/some/object/name,来自下游服务的 Location 响应头值 object-service.prod.example.net/v2/some/object/id 将被重写为 api.example.com/some/object/id
对于一个请求 POST api.example.com/some/object/name,来自下游服务的 Location 响应头值 object-service.prod.example.net/v2/some/object/id 将被重写为 api.example.com/some/object/id
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
RewritePath:
重写路径网关过滤器工厂
重写路径网关过滤器工厂
用于动态地修改请求的路径,然后再将其发送给下游服务。
参数
path regexp
路径正则表达式
路径正则表达式
一个 Java 正则表达式**,用于匹配传入请求的路径部分。它定义了哪些路径段需要被捕获和处理。
replacement
替换值
替换值
用于构建新路径**的模板字符串。它可以使用正则表达式中捕获的组(如 segment)。
示例
对于一个请求路径为 /red/blue,此过滤器会在向下游服务发送请求之前,将路径设置为 /blue。请注意,在 replacement 参数中的 $ 需要转义为 $\,这是为了符合 YAML 规范(${segment} 在 YAML 中有特殊含义,需要这样转义才能表示捕获组的引用)。
对于一个请求路径为 /red/blue,此过滤器会在向下游服务发送请求之前,将路径设置为 /blue。请注意,在 replacement 参数中的 $ 需要转义为 $\,这是为了符合 YAML 规范(${segment} 在 YAML 中有特殊含义,需要这样转义才能表示捕获组的引用)。
spring:
cloud:
gateway:
routes:
- id: rewritepath_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
predicates:
- Path=/red/** # 只匹配以 /red/ 开头的路径
filters:
- RewritePath=/red/?(?<segment>.*), /$\{segment} # 重写路径过滤器
cloud:
gateway:
routes:
- id: rewritepath_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
predicates:
- Path=/red/** # 只匹配以 /red/ 开头的路径
filters:
- RewritePath=/red/?(?<segment>.*), /$\{segment} # 重写路径过滤器
RewriteRequestParameter:
重写请求参数网关过滤器工厂
重写请求参数网关过滤器工厂
在网关将请求转发到下游服务之前,动态修改请求中的特定查询字符串参数
参数
name(第一个参数): 指定要重写的请求参数的名称**(例如 campaign)
replacement(第二个参数): 指定新的参数值**(例如 fall2023)
注意
同名参数的场景: 如果有多个具有相同名称的请求参数,过滤器会将它们全部替换为一个单一的参数,其值为指定的 replacement。
参数不存在的场景: 如果在请求中找不到指定名称的请求参数,过滤器不会做任何更改。
示例
对于一个指向 /products?campaign=old 的请求,此过滤器会将请求参数 **campaign 的值重写为 fall2023**,然后发送到下游服务 https://example.org。下游服务接收到的请求将是 /products?campaign=fall2023。
对于一个指向 /products?campaign=old 的请求,此过滤器会将请求参数 **campaign 的值重写为 fall2023**,然后发送到下游服务 https://example.org。下游服务接收到的请求将是 /products?campaign=fall2023。
spring:
cloud:
gateway:
routes:
- id: rewriterequestparameter_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
predicates:
- Path=/products # 匹配路径 /products
filters:
- RewriteRequestParameter=campaign,fall2023 # 重写请求参数:将 campaign 的值设为 fall2023
cloud:
gateway:
routes:
- id: rewriterequestparameter_route # 路由ID
uri: https://example.org # 目标URI (下游服务)
predicates:
- Path=/products # 匹配路径 /products
filters:
- RewriteRequestParameter=campaign,fall2023 # 重写请求参数:将 campaign 的值设为 fall2023
RewriteResponseHeader:
重写响应头网关过滤器工厂
重写响应头网关过滤器工厂
网关收到下游服务的响应之后,但在将响应返回给原始客户端之前。它用于修改特定响应头(Header)的值内容。
参数
name(第一个参数): 指定要重写的响应头的名称**(例如 X-Response-Red)
regexp(第二个参数): 一个 Java 正则表达式字符串。这个正则表达式将用于匹配**原始响应头值中需要被替换的部分。
replacement(第三个参数): 用于替换被 regexp 匹配到的部分的字符串
示例
对于一个响应头的值为 /42?user=ford&password=omg!what&flag=true 的情况(例如,头 X-Response-Red 的值),此过滤器在网关处理(转发)了下游服务的响应之后,会将其设置为 /42?user=ford&password=***&flag=true。
对于一个响应头的值为 /42?user=ford&password=omg!what&flag=true 的情况(例如,头 X-Response-Red 的值),此过滤器在网关处理(转发)了下游服务的响应之后,会将其设置为 /42?user=ford&password=***&flag=true。
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*** # 重写响应头过滤器
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*** # 重写响应头过滤器
注意
在 replacement 参数中,如果你想表示正则捕获组的引用(如 $1, $2 等)或文字 $ 字符,在 YAML 中必须使用 $\ 来表示 $。这是由 YAML 规范决定的($ 在 YAML 中是变量标识符的特殊字符,需要转义)。
SaveSession:
保存会话网关过滤器工厂
保存会话网关过滤器工厂
在请求被转发到 uri 定义的下游服务之前,调用 WebSession.save() 方法
注意
使用类似于 Spring Session(配合惰性数据存储—— lazy data store)
确保在将请求转发到下游服务之前,会话状态(Session State)已经被保存到持久化存储中。
如果您将 Spring Security 与 Spring Session 集成,并且需要确保在向下游服务转发请求时,安全相关的详细信息(如认证信息)已经正确地序列化并保存到会话中,那么使用这个过滤器是至关重要的。
SecureHeaders:
安全头网关过滤器工厂
安全头网关过滤器工厂
自动添加一组推荐的安全响应头,增强应用的安全性。
配置
全局配置
spring:
cloud:
gateway:
filter:
secure-headers:
disable: x-frame-options, strict-transport-security # 禁用 X-Frame-Options 和 Strict-Transport-Security
cloud:
gateway:
filter:
secure-headers:
disable: x-frame-options, strict-transport-security # 禁用 X-Frame-Options 和 Strict-Transport-Security
路由级配置
- id: secureheaders_route
uri: http://example.org
predicates:
- Path=/**
filters:
- name: SecureHeaders
args:
disable: x-frame-options # 仅在此路由禁用 X-Frame-Options
uri: http://example.org
predicates:
- Path=/**
filters:
- name: SecureHeaders
args:
disable: x-frame-options # 仅在此路由禁用 X-Frame-Options
权限策略 (Permissions-Policy) 选项
禁用 (disable): 指定不添加哪些安全头部(使用小写全名)
自定义值: 通过属性覆盖特定安全头部的默认值。
启用额外头部 (enable): 如 permissions-policy。
SetPath:
设置路径网关过滤器工厂
设置路径网关过滤器工厂
修改传入请求的路径,然后向下游服务(uri 指定的目标服务)发起请求
示例
Path 断言 /red/{segment} 从请求路径中提取匹配的部分(例如 /red/blue 中的 blue)并将其存储在变量 segment 中。
SetPath=/{segment} 过滤器接收到这个变量 segment(其值为 blue),并使用该值构建一个新的路径(/blue)。
Path 断言 /red/{segment} 从请求路径中提取匹配的部分(例如 /red/blue 中的 blue)并将其存储在变量 segment 中。
SetPath=/{segment} 过滤器接收到这个变量 segment(其值为 blue),并使用该值构建一个新的路径(/blue)。
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
模板语法
使用 Spring Framework 的 URI 模板语法 ({variableName}),支持更复杂的模板,例如 /newpath/{var1}/sub/{var2}。只要 Path 断言定义的路径中包含相应的变量,这些变量就能在 SetPath 的模板中被使用。
SetRequestHeader:
设置请求头网关过滤器工厂
设置请求头网关过滤器工厂
设置(或更准确地说是覆盖)发送给下游服务的 HTTP 请求头
参数
name: 要设置/覆盖的 HTTP 请求头的名称 (例如 X-Request-Red, Authorization, foo)
value: 要设置的值 (例如 Blue, Bearer someToken, bar-{segment})
注意
替换而非添加: 如果请求中已存在同名头,过滤器会删除所有现有的值并用配置的值覆盖它。
如果不存在: 如果请求中不存在该头,过滤器会添加这个请求头。
示例:
是替换(而不是添加)所有给定名称(X-Request-Red)的请求头。
如果传入的请求已经包含 X-Request-Red:1234 这个头,
它将被完全替换为 X-Request-Red:Blue,
这是下游服务最终会收到的值
是替换(而不是添加)所有给定名称(X-Request-Red)的请求头。
如果传入的请求已经包含 X-Request-Red:1234 这个头,
它将被完全替换为 X-Request-Red:Blue,
这是下游服务最终会收到的值
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
示例
支持 URI 变量
支持 URI 变量
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
SetResponseHeader:
设置响应头网关过滤器工厂
设置响应头网关过滤器工厂
设置(或更准确地说是覆盖)从下游服务返回给网关客户端的 HTTP 响应头。
参数
name: 要设置/覆盖的 HTTP 响应头的名称 (例如 X-Response-Red, Cache-Control, foo)。
value: 要设置的值 (例如 Blue, max-age=3600, bar-{segment})。
注意
替换而非添加: 如果下游服务的响应中已存在同名头,过滤器会删除所有现有的值并用配置的值覆盖它。
如果不存在: 如果下游服务的响应中不存在该头,过滤器会添加这个响应头。
修改点: 在网关接收到下游服务的响应之后,发送给最终客户端之前。
示例:
如果下游服务器返回的响应中包含 X-Response-Red:1234 这个头,网关将把该头值替换为 X-Response-Red:Blue,最终网关客户端(例如浏览器或应用程序)接收到的就是这个修改后的值。
如果下游服务器返回的响应中包含 X-Response-Red:1234 这个头,网关将把该头值替换为 X-Response-Red:Blue,最终网关客户端(例如浏览器或应用程序)接收到的就是这个修改后的值。
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
示例
支持 URI 变量
支持 URI 变量
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
SetStatus:
设置状态网关过滤器工厂
设置状态网关过滤器工厂
强制覆盖网关返回给客户端的响应的 HTTP 状态码。
参数
status: 要设置的 HTTP 状态码。接受:
整数格式: 401, 404, 500 等。
枚举字符串格式: BAD_REQUEST, NOT_FOUND, INTERNAL_SERVER_ERROR, UNAUTHORIZED, FORBIDDEN 等 (不区分大小写)。
两种形式的效果相同:将响应的状态码设置为指定的值。
示例
无论使用 UNAUTHORIZED 字符串还是 401 整数,响应的 HTTP 状态码都会被设置为 401 (未授权)。
无论使用 UNAUTHORIZED 字符串还是 401 整数,响应的 HTTP 状态码都会被设置为 401 (未授权)。
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=UNAUTHORIZED
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=UNAUTHORIZED
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
示例
保留原始状态码
保留原始状态码
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
StripPrefix:
剥离路径前缀网关过滤器工厂
剥离路径前缀网关过滤器工厂
修剪请求路径的前缀部分,适用于网关路径与下游微服务内部路径不匹配的场景。
参数
parts: 需要从路径开头移除的段(segment)的数量。路径段是由斜杠 / 分隔的部分。
示例
当一个请求通过网关发送到路径 /name/blue/red 时。
StripPrefix=2 过滤器会移除路径开头的两段:/name 和 /blue。
最终转发给下游服务 https://nameservice 的请求路径将变为 /red。
下游服务 nameservice 实际接收到的请求访问的是它的 /red 端点。
当一个请求通过网关发送到路径 /name/blue/red 时。
StripPrefix=2 过滤器会移除路径开头的两段:/name 和 /blue。
最终转发给下游服务 https://nameservice 的请求路径将变为 /red。
下游服务 nameservice 实际接收到的请求访问的是它的 /red 端点。
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
Retry:
重试网关过滤器工厂
重试网关过滤器工厂
参数
retries 重试次数(默认 3 次)
statuses 触发重试的 HTTP 状态码(如 BAD_GATEWAY)
methods 触发重试的 HTTP 方法(如 GET, POST)
exceptions 触发重试的异常(默认 IOException, TimeoutException)
backoff 指数退避策略
firstBackoff:初始间隔(默认禁用)
maxBackoff:最大间隔
factor:退避倍数
basedOnPreviousValue:是否基于前次间隔计算
jitter 随机抖动:
randomFactor:抖动范围(默认禁用)
timeout 重试操作超时时间(默认无限制)
示例
spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3 # 重试次数
statuses: BAD_GATEWAY # 触发状态码
methods: GET,POST # 触发方法
backoff:
firstBackoff: 10ms # 初始间隔
maxBackoff: 50ms # 最大间隔
factor: 2 # 指数因子
basedOnPreviousValue: false
jitter:
randomFactor: 0.5 # 抖动因子 (50%)
timeout: 100ms # 超时时间
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3 # 重试次数
statuses: BAD_GATEWAY # 触发状态码
methods: GET,POST # 触发方法
backoff:
firstBackoff: 10ms # 初始间隔
maxBackoff: 50ms # 最大间隔
factor: 2 # 指数因子
basedOnPreviousValue: false
jitter:
randomFactor: 0.5 # 抖动因子 (50%)
timeout: 100ms # 超时时间
示例
两种等价配置方式
两种等价配置方式
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: https://example.org
filters:
- name: Retry #完整 YAML 配置
args:
retries: 3
statuses: INTERNAL_SERVER_ERROR
methods: GET
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
jitter:
randomFactor: 0.5
timeout: 100ms
#快捷语法(参数顺序固定)
- id: retryshortcut_route
uri: https://example.org
filters:
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false,0.5,100ms #快捷语法(参数顺序固定)
cloud:
gateway:
routes:
- id: retry_route
uri: https://example.org
filters:
- name: Retry #完整 YAML 配置
args:
retries: 3
statuses: INTERNAL_SERVER_ERROR
methods: GET
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
jitter:
randomFactor: 0.5
timeout: 100ms
#快捷语法(参数顺序固定)
- id: retryshortcut_route
uri: https://example.org
filters:
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false,0.5,100ms #快捷语法(参数顺序固定)
注意
forward: 端点约束
若目标端点返回错误状态码(如 ResponseEntity),重试将失效!
正确做法:端点需抛出异常(如 throw Exception)或返回错误信号(如 Mono.error(ex))。
下游过滤器影响
重试会重新执行 所有后续过滤器,确保这些过滤器支持幂等操作。
请求体缓存风险
对带 Body 的请求(如 POST),请求体会被完整缓存,可能导致网关内存溢出。
缓存位置:ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR(类型为 DataBuffer)。
RequestSize:
请求大小网关过滤器工厂
请求大小网关过滤器工厂
限制 HTTP 请求的 Body 大小,防止过大请求到达下游服务。
maxSize 参数
类型为 DataSize
值可以定义为一个数字,后跟一个可选的 DataUnit 后缀,例如 'KB'(千字节)或 'MB'(兆字节)。
默认单位为 'B'(字节)。
它表示允许的请求大小限制(以字节为单位)。
示例
最大允许请求大小为 5,000,000 字节 (5 MB)
最大允许请求大小为 5,000,000 字节 (5 MB)
spring:
cloud:
gateway:
routes:
- id: request_size_route # 路由ID
uri: http://localhost:8080/upload # 目标服务地址
predicates:
- Path=/upload # 匹配路径为 /upload 的请求
filters:
- name: RequestSize # 过滤器名称
args:
maxSize: 5000000 # 最大允许请求大小为 5,000,000 字节 (5 MB)
cloud:
gateway:
routes:
- id: request_size_route # 路由ID
uri: http://localhost:8080/upload # 目标服务地址
predicates:
- Path=/upload # 匹配路径为 /upload 的请求
filters:
- name: RequestSize # 过滤器名称
args:
maxSize: 5000000 # 最大允许请求大小为 5,000,000 字节 (5 MB)
超出限制处理
直接拒绝请求,不转发至下游。
返回 HTTP 状态码 **413 Payload Too Large**。
在响应头 **errorMessage** 中提供详细的错误信息(当前请求大小和允许的限制)。
SetRequestHostHeader:
设置请求主机头网关过滤器工厂
设置请求主机头网关过滤器工厂
强制覆盖(替换)发送给下游服务的 HTTP 请求中的 Host 请求头
host参数
想要设置的新 Host 头的值 (字符串类型,例如 "example.org", "api.service.com:8080")
示例
spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route # 路由 ID
uri: http://localhost:8080/headers # 目标服务地址
predicates:
- Path=/headers # 匹配路径为 /headers 的请求
filters:
- name: SetRequestHostHeader # 过滤器名称
args:
host: example.org # 要设置的 Host 头新值
cloud:
gateway:
routes:
- id: set_request_host_header_route # 路由 ID
uri: http://localhost:8080/headers # 目标服务地址
predicates:
- Path=/headers # 匹配路径为 /headers 的请求
filters:
- name: SetRequestHostHeader # 过滤器名称
args:
host: example.org # 要设置的 Host 头新值
TokenRelay:
令牌中继网关过滤器工厂
令牌中继网关过滤器工厂
令牌中继 (Token Relay) 是指一个 OAuth2 消费者扮演 客户端 (Client) 的角色,将传入的令牌 (Token) 转发到出站资源请求中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
TokenRelay GatewayFilter 使得 Spring Cloud Gateway 能够透明地将 OAuth2 访问令牌从客户端传播到下游服务,是实现 API 网关安全令牌中继的核心组件。它支持两种模式:使用特定客户端配置获取令牌,或直接传递当前登录用户的令牌。使用时必须确保正确配置了 OAuth2 客户端依赖和属性,并了解其默认内存存储的限制,为生产环境评估存储需求。
接受一个可选的参数 clientRegistrationId
示例
指定了 clientRegistrationId 参数,它用于从配置的 客户端注册 (ClientRegistration) 中获取并转发相应的 OAuth2 访问令牌
指定了 clientRegistrationId 参数,它用于从配置的 客户端注册 (ClientRegistration) 中获取并转发相应的 OAuth2 访问令牌
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay("myregistrationid")) // 指定 clientRegistrationId
.uri("http://localhost:9000")) // 目标服务
.build();
}
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay("myregistrationid")) // 指定 clientRegistrationId
.uri("http://localhost:9000")) // 目标服务
.build();
}
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000 # 目标服务
predicates:
- Path=/resource # 匹配路径
filters:
- TokenRelay=myregistrationid # 指定 clientRegistrationId
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000 # 目标服务
predicates:
- Path=/resource # 匹配路径
filters:
- TokenRelay=myregistrationid # 指定 clientRegistrationId
示例
转发当前已认证用户的 OAuth2 访问令牌(当使用 oauth2Login() 对用户进行身份验证时)
转发当前已认证用户的 OAuth2 访问令牌(当使用 oauth2Login() 对用户进行身份验证时)
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay()) // 不指定 clientRegistrationId,使用当前用户的登录令牌
.uri("http://localhost:9000"))
.build();
}
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay()) // 不指定 clientRegistrationId,使用当前用户的登录令牌
.uri("http://localhost:9000"))
.build();
}
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay= # 空参数表示使用当前用户的令牌 (或者直接写 - TokenRelay)
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay= # 空参数表示使用当前用户的令牌 (或者直接写 - TokenRelay)
流程
该过滤器会从当前已认证用户的安全上下文中提取 OAuth2 访问令牌。
如果配置了 clientRegistrationId 参数,它会尝试获取与该特定客户端注册相关的访问令牌。
如果省略了 clientRegistrationId 参数,它会尝试获取当前已登录用户自身的访问令牌(通常是在用户通过网关进行 oauth2Login() 登录时获得的)。
无论使用哪种方式,过滤器都会将提取到的访问令牌放入向下游服务发送的 HTTP 请求的 Authorization 头 (通常形如 Bearer <token>) 中。
注意
创建条件: TokenRelayGatewayFilterFactory 这个 Bean 仅在配置了正确的 OAuth2 客户端属性时才会被创建。这些属性 (spring.security.oauth2.client.*) 会触发创建 ReactiveClientRegistrationRepository Bean(存储客户端注册信息)。
默认存储方式: TokenRelayGatewayFilterFactory 使用的默认 ReactiveOAuth2AuthorizedClientService 实现是一个 内存存储 (in-memory data store)。
生产环境存储: 如果你需要一个更健壮的解决方案(例如支持集群部署、持久化存储授权状态),你需要提供 自定义的 ReactiveOAuth2AuthorizedClientService 实现 (例如基于 Redis 或数据库的实现)。

收藏
0 条评论
下一页