Spring Cloud Gateway 默认的filter功能和执行顺序介绍

让我给你讲解一下 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 被启用了:RouteToRequestUrlFilterWebClientHttpRoutingFilter。他们的执行顺序应该是按照上面所示的顺序。

示例 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技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 一个新手站长如何整站搬家?网站搬家全过程分享

    下面是一个新手站长如何整站搬家的完整攻略。 1.备份原网站内容 在开始整站搬家前,第一步非常重要的是备份原网站内容。我们可以使用FTP客户端将整站内容从服务器下载下来并保存到本地。备份的目的是在搬家过程中出现问题时可以及时恢复原网站。 2.选择新的主机或云服务器 在整站搬家前,需要先选择新的主机或云服务器。选择合适的主机或云服务器对于网站的速度、稳定性和安全…

    other 2023年6月27日
    00
  • JVM内存结构划分实例解析

    JVM内存结构划分实例解析 JVM(Java虚拟机)是Java程序的运行环境,它将程序的执行过程抽象为一组内存区域。这些内存区域被划分为不同的部分,每个部分有不同的作用和生命周期。本文将详细讲解JVM内存结构的划分,并提供两个示例说明。 JVM内存结构划分 JVM内存结构主要分为以下几个部分: 方法区(Method Area):用于存储类的结构信息,包括类的…

    other 2023年8月2日
    00
  • 非常详细的/etc/passwd解释

    非常详细的 /etc/passwd 解释 在类UNIX操作系统中,/etc/passwd是存储本地用户信息的文件。在本篇文章中,将会详细解释/etc/passwd文件的各个字段以及它们是如何被用来控制用户的访问。 文件格式 /etc/passwd 文件由一行一行的文本记录构成,每一行都表示一个本地系统用户。每一行由冒号(::)分隔成了七个字段。以下是一些范例…

    其他 2023年3月28日
    00
  • 微信小程序自定义导航栏及其封装的全过程

    下面我将为您详细讲解“微信小程序自定义导航栏及其封装的全过程”的完整攻略。 导航栏简介 微信小程序中,导航栏一般分为两种类型:系统默认导航栏和自定义导航栏。默认导航栏的样式和功能都是微信小程序自带的,而自定义导航栏则是开发者可以根据自己的喜好自由定义的,同时自定义导航栏也具有更强的灵活性和可扩展性。 自定义导航栏实现步骤 以下是实现自定义导航栏的具体步骤: …

    other 2023年6月25日
    00
  • C语言中求余运算符的使用解读

    当我们在C语言中使用求余运算符时(%),会得到两个数相除后的余数。下面是关于C语言中求余运算符的使用解读的完整攻略: 什么是求余运算符? 求余运算符是一种二元运算符,通常表示为百分号(%),用于计算两个数相除后的余数。 求余运算符的使用方法 我们可以使用如下语法来使用求余运算符: remainder = dividend % divisor; 其中,divi…

    other 2023年6月27日
    00
  • javascript中href和replace比较

    当然,我很乐意为您提供关于“JavaScript中href和replace比较”的完整攻略。以下是详细的步骤说明: 步骤说明 在JavaScript,href和replace都是用于跳转页面的方法。它们的区别在于href会在当前页面打开一个新的,而replace则会在页面替换为新的页面。 href 使用href方法跳转页面的步骤如下: 获取要跳转的地址。 使…

    other 2023年5月9日
    00
  • js封装可使用的构造函数继承用法分析

    JS封装可使用的构造函数继承用法分析攻略 在JavaScript中,构造函数继承是一种常见的面向对象编程技术,它允许我们创建一个新的对象,该对象继承了另一个对象的属性和方法。这种继承方式可以通过封装可使用的构造函数来实现。下面是一个详细的攻略,介绍了如何使用构造函数继承。 1. 创建父类构造函数 首先,我们需要创建一个父类构造函数,该构造函数包含要继承的属性…

    other 2023年8月6日
    00
  • JS中IP地址与整数相互转换的实现代码

    当需要在JavaScript中进行IP地址和整数之间的转换时,可以使用一些位运算和字符串处理的技巧来实现。下面是一个完整的攻略,包含了IP地址转整数和整数转IP地址的实现代码。 IP地址转整数 要将IP地址转换为整数,可以按照以下步骤进行: 首先,将IP地址字符串拆分成四个部分,使用点号作为分隔符。例如,将IP地址\”192.168.0.1\”拆分为[\”1…

    other 2023年7月31日
    00
合作推广
合作推广
分享本页
返回顶部