让我给你讲解一下 Spring Cloud Gateway 默认的 filter 功能和执行顺序。
简介
Spring Cloud Gateway 是一个基于 Spring Boot 2.x 的网关服务,它提供了许多强大的特性,其中就包括了 filter 功能。filter (过滤器)是 Spring Cloud Gateway 提供的一个可以在请求路由之前或之后对请求和响应进行修改和处理的组件。Spring Cloud Gateway 是通过 filter 链来对请求进行处理的,用户可以通过自定义 filter 来实现自己的需求。
默认的 filter 功能
Spring Cloud Gateway 提供了一些默认的 filter 功能,它们按照一定的顺序在 filter 链中执行。下面会简单介绍一下这些默认的 filter 功能及其执行顺序。
1. 前置 filter
前置 filter 把请求路由前的处理都放在这个 filter 里面,包括设置请求头、请求参数、重写请求等操作。默认的前置 filter 就是 ForwardRoutingFilter
,它的作用是将请求转发到实际的服务实例中。
2. GatewayFilterChain filter
这个 filter 负责将请求转发到下一个 filter。这实际上是一个 filter 责任链,每一次请求都会从这里开始,然后依次执行 filter 链中的所有 filter。
3. 路径匹配 filter
路径匹配 filter 的作用是将请求与路由规则进行匹配,找到符合条件的路由,然后将请求发送到实际的服务实例中。路径匹配 filter 的默认实现是 RouteToRequestUrlFilter
。
4. 过滤器 filter
过滤器 filter 是 Spring Cloud Gateway 中最重要的一个组件,它负责过滤和修改请求和响应。Spring Cloud Gateway 提供了多种 filter,用户可以根据实际需求自己选择或者自定义。
5. 后置 filter
后置 filter 是在请求处理完之后执行的 filter,可以做一些清理工作。默认的后置 filter 是 ForwardRoutingFilter
。
filter 执行顺序
filter 的执行顺序固定,每个 filter 都有一个固定的顺序,按照这个顺序依次执行。下面是 Spring Cloud Gateway 中默认 filter 的执行顺序:
ordering:
- ForwardRoutingFilter
- GatewayMetricsFilter
- RouteToRequestUrlFilter
- AdaptiveLoadBalancerClientFilter
- WebClientHttpRoutingFilter
- WebClientWriteResponseFilter
示例说明
示例 1
假设我们现在有一个微服务应用,使用了 Spring Cloud Gateway 作为网关服务,其中定义了一个路由规则:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/user/**
这个路由规则实现了把所有以 /user
开头的请求都转发到实际的服务实例中去。
在这个路由规则中,有两个 filter 被启用了:RouteToRequestUrlFilter
和 WebClientHttpRoutingFilter
。他们的执行顺序应该是按照上面所示的顺序。
示例 2
假设我们需要对请求进行验证,只有当请求头中包含了正确的 token 时,才能继续访问。那么我们可以自定义一个 filter 来完成这个功能。
首先创建一个 TokenFilter
类,代码如下:
@Component
public class TokenFilter implements GatewayFilter {
private static final String TOKEN_HEADER = "Authorization";
private static final String TOKEN_PREFIX = "Bearer ";
private static final String SECRET_KEY = "mysecretkey";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst(TOKEN_HEADER);
if (token != null && token.startsWith(TOKEN_PREFIX)) {
String jwt = token.substring(TOKEN_PREFIX.length());
if (validateToken(jwt)) {
return chain.filter(exchange);
}
}
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
private boolean validateToken(String jwt) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build();
DecodedJWT decodedJWT = verifier.verify(jwt);
return true;
} catch (JWTVerificationException e) {
return false;
}
}
}
这个 TokenFilter
类继承了 GatewayFilter
接口,并实现了其中的 filter
方法。在这个方法中,我们首先获取到请求头中的 token,然后判断它是否是有效的 token。如果是有效的 token,就调用 chain.filter(exchange)
继续执行 filter 链中的下一个 filter;否则,直接返回一个 401 状态码,拒绝请求。
接下来,我们需要注册这个 filter。在 Spring Boot 的配置文件中加上以下内容:
spring:
cloud:
gateway:
default-filters:
- name: TokenFilter
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/user/**
在这个配置中,我们加上了 default-filters
属性,并将 TokenFilter
添加到其中。这个过程是在 Spring Cloud Gateway 启动时自动完成的。之后,我们还需要把 TokenFilter
注入到 Spring 容器中,代码如下:
@SpringBootApplication
public class GatewayApplication {
@Bean
public TokenFilter tokenFilter() {
return new TokenFilter();
}
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
现在,重启 Spring Cloud Gateway,就可以看到我们的 TokenFilter
已经生效了。在运行 Spring Cloud Gateway 的时候,我们可以使用 curl
命令来验证一下它的效果:
curl -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.rGtJfVJvZ5hGqT_WG-_siKgNM21yszW5UsQHERzUuec' http://localhost:8080/user/1
其中,Authorization
是我们用来验证的 token,http://localhost:8080/user/1
是我们的 API 地址。如果验证通过,就可以正常访问 API;如果验证不通过,则返回 401 状态码。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Cloud Gateway 默认的filter功能和执行顺序介绍 - Python技术站