5. 路由谓词工厂
Spring Cloud Gateway 将路由匹配为 Spring WebFlux 的一部分HandlerMapping
基础设施。 Spring Cloud Gateway 包括许多内置的路由谓词工厂。所有这些谓词都匹配 HTTP 请求的不同属性。您可以将多个路由谓词工厂与逻辑and
语句。
5.1. After 路由谓词工厂
这After
route 谓词工厂接受一个参数,一个datetime
(这是一个 javaZonedDateTime
). 此谓词匹配在指定日期时间之后发生的请求。以下示例配置 after 路由谓词:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
此路线与 2017 年 1 月 20 日 17:42 山区时间(丹佛)之后提出的任何请求相匹配。
5.2. Before Route谓词工厂
这Before
route 谓词工厂接受一个参数,一个datetime
(这是一个 javaZonedDateTime
). 此谓词匹配在指定datetime
. 以下示例配置了 before route 谓词:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
此路线符合山区时间 2017 年 1 月 20 日 17:42(丹佛)之前提出的任何请求。
5.3. Between 路由谓词工厂
这Between
route 谓词工厂采用两个参数,datetime1
和datetime2
哪些是 JavaZonedDateTime
对象。 此谓词匹配在datetime1
和之前datetime2
. 这datetime2
参数必须在datetime1
. 以下示例配置了 between route 谓词:
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]
此路线与 2017 年 1 月 20 日 17:42 山区时间(丹佛)之后和 2017 年 1 月 21 日 17:42 山区时间(丹佛)之前提出的任何请求匹配。这对于维护窗口可能很有用。
5.4. Cookie 路由谓词工厂
这Cookie
route 谓词工厂采用两个参数,即 cookiename
和regexp
(这是一个 Java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的 cookie。以下示例配置 cookie 路由谓词工厂:
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
此路由匹配具有名为chocolate
其值与ch.p
正则表达式。
5.5. 标头路由谓词工厂
这Header
route 谓词工厂采用两个参数,即header
和regexp
(这是一个 Java 正则表达式)。此谓词与具有给定名称的标头匹配,其值与正则表达式匹配。以下示例配置标头路由谓词:
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
如果请求具有名为X-Request-Id
其值与\d+
正则表达式(即,它的值为一个或多个数字)。
5.6. 主机路由谓词工厂
这Host
路由谓词工厂采用一个参数:主机名列表patterns
. 该图案是Ant风格的图案,带有.
作为分隔符。此谓词与Host
标头。以下示例配置主机路由谓词:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
URI 模板变量(例如{sub}.myhost.org
) 也受支持。
如果请求具有Host
标头,值为www.somehost.org
或beta.somehost.org
或www.anotherhost.org
.
此谓词提取 URI 模板变量(例如sub
,在前面的示例中定义)作为名称和值的映射,并将其放置在ServerWebExchange.getAttributes()
在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
. 然后,这些值可供GatewayFilter
工厂
5.7. 方法路由谓词工厂
这Method
路由谓词工厂采用methods
参数,该参数是一个或多个参数:要匹配的 HTTP 方法。以下示例配置方法路由谓词:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
如果请求方法是GET
或POST
.
5.8. 路径路由谓词工厂
这Path
路由谓词工厂接受两个参数:Spring 列表PathMatcher
patterns
以及一个名为matchTrailingSlash
(默认为true
). 以下示例配置路径路由谓词:
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
如果请求路径是,则此路由匹配,例如:/red/1
或/red/1/
或/red/blue
或/blue/green
.
如果matchTrailingSlash
设置为false
,然后请求路径/red/1/
将不匹配。
此谓词提取 URI 模板变量(例如segment
,在前面的示例中定义)作为名称和值的映射,并将其放置在ServerWebExchange.getAttributes()
在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
. 然后,这些值可供GatewayFilter
工厂
实用程序方法(称为get
) 可以更轻松地访问这些变量。
以下示例演示如何使用get
方法:
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
String segment = uriVariables.get("segment");
5.9. 查询路由谓词工厂
这Query
路由谓词工厂采用两个参数:必需的param
和可选的regexp
(这是一个 Java 正则表达式)。
以下示例配置查询路由谓词:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
如果请求包含green
query 参数。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
如果请求包含red
query 参数,其值与gree.
正则表达式,所以green
和greet
会匹配。
5.10. RemoteAddr路由谓词工厂
这RemoteAddr
路由谓词工厂采用列表(最小大小 1)sources
,它们是 CIDR 表示法(IPv4 或 IPv6)字符串,例如192.168.0.1/16
(其中192.168.0.1
是一个 IP 地址,并且16
是子网掩码)。
以下示例配置 RemoteAddr 路由谓词:
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
如果请求的远程地址是192.168.1.10
.
5.10.1. 修改远程地址的解析方式
默认情况下,RemoteAddr 路由谓词工厂使用传入请求中的远程地址。 如果 Spring Cloud Gateway 位于代理层后面,则这可能与实际的客户端 IP 地址不匹配。
您可以通过设置自定义RemoteAddressResolver
.
Spring Cloud Gateway 附带一个基于 X-Forwarded-For 标头的非默认远程地址解析器,XForwardedRemoteAddressResolver
.
XForwardedRemoteAddressResolver
有两个静态构造函数方法,它们采用不同的安全方法:
-
XForwardedRemoteAddressResolver::trustAll
返回一个RemoteAddressResolver
始终采用在X-Forwarded-For
页眉。 此方法容易受到欺骗,因为恶意客户端可能会为X-Forwarded-For
,这将被解析器接受。 -
XForwardedRemoteAddressResolver::maxTrustedIndex
采用与 Spring Cloud Gateway 前面运行的受信任基础结构数量相关的索引。例如,如果 Spring Cloud Gateway 只能通过 HAProxy 访问,则应使用值 1。如果在访问 Spring Cloud Gateway 之前需要两个受信任基础结构跃点,则应使用值 2。
考虑以下标头值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
以下内容maxTrustedIndex
值产生以下远程地址:
maxTrustedIndex |
结果 |
---|---|
[ |
(无效, |
1 |
0.0.0.3 |
2 |
0.0.0.2 |
3 |
0.0.0.1 |
[4, |
0.0.0.1 |
以下示例显示了如何使用 Java 实现相同的配置:
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
.maxTrustedIndex(1);
...
.route("direct-route",
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
.uri("https://downstream1")
.route("proxied-route",
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
.uri("https://downstream2")
)
5.11. 权重路由谓词工厂
这Weight
route 谓词工厂接受两个参数: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
此路由将转发 ~80% 的流量到 weighthigh.org,将 ~20% 的流量转发到 weighlow.org
5.12. XForwarded Remote Addr Route 谓词工厂
这XForwarded Remote Addr
路由谓词工厂采用列表(最小大小 1)sources
,它们是 CIDR 表示法(IPv4 或 IPv6)字符串,例如192.168.0.1/16
(其中192.168.0.1
是一个 IP 地址,并且16
是子网掩码)。
此路由谓词允许根据X-Forwarded-For
HTTP 标头。
这可以与反向代理一起使用,例如负载均衡器或 Web 应用程序防火墙,其中仅当请求来自这些请求使用的受信任 IP 地址列表时才应允许该请求反向代理。
以下示例配置 XForwardedRemoteAddr 路由谓词:
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
如果X-Forwarded-For
header 包含,例如,192.168.1.10
.