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

yizhihongxing

让我给你讲解一下 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日

相关文章

  • 【Unity】3.1 利用内置的3D对象创建三维模型

    以下是利用内置的3D对象创建三维模型的完整攻略,包括使用步骤和两个示例说明。 使用步骤 使用内置的3D对象创建三维模型的步骤如下: 打开Unity编辑器,创建一个新的3D项目。 在场景中创建一个空对象,作为模型的父对象。 从菜单栏中选择GameObject > 3D Object,选择一个内置的3D对象,例如Cube、Sphere或Cylinder。 …

    other 2023年5月7日
    00
  • 前端开发之JS生成32位随机数的方法举例

    前端开发之JS生成32位随机数的方法举例 在前端开发中,生成随机数是一项常见的任务。本攻略将详细介绍如何使用JavaScript生成32位随机数,并提供两个示例说明。 方法一:使用Math.random()函数 JavaScript中的Math.random()函数可以生成一个0到1之间的随机数。我们可以利用该函数生成32位随机数的一部分,然后将其拼接起来。…

    other 2023年7月28日
    00
  • 详解react关于事件绑定this的四种方式

    下面我将详细讲解“详解react关于事件绑定this的四种方式”的完整攻略。 1. bind方法 bind方法是es5中新增的方法,可以用来改变this的指向。在React中,我们可以通过bind方法来绑定this,将事件执行上下文中的this设置为组件实例对象。 示例代码: class MyComponent extends React.Component…

    other 2023年6月26日
    00
  • python之tkinter.messagebox弹窗

    Python之tkinter.messagebox弹窗 在Tkinter库中,messagebox是一种弹窗组件,可以用于显示消息、警告、提示等信息。在这篇文章中,我们将探讨如何使用tkinter.messagebox弹窗在python应用程序中显示消息和警告。 安装Tkinter 在开始本文之前,请确保你已经安装了tkinter库。虽然tkinter在大多…

    其他 2023年3月28日
    00
  • spark遇到的错误1-内存不足

    概述 在使用Spark进行大数据处理时,可能会遇到内存不足的错误。本文将为您提供一份完整攻略,介绍如何解决Spark遇到的内存不足错误,并提供两个示例说明。 解决内存不足错误的步骤 步骤1:调整Spark的内存设置 在Spark遇到内存不足错误时,我们可以尝试调整Spark的内存设置。可以使用以下命令来调整Spark的内存设置: spark-submit -…

    other 2023年5月5日
    00
  • qt笔记——moc(莫克)

    Qt笔记——moc(莫克)的完整攻略 1. 基本介绍 moc(Meta-Object Compiler)是Qt中的一个元对象编译器,可以将C++代码中的元对象信息提取出来,并生成相应的代码。在Qt中,元对象是指那些具有信号和槽制的类,moc可以将这些类中的信号和槽信息提取出来,并生成相应的代码,使得这些类可以支持信号和槽机制。 2. 用法 以下是使用moc的…

    other 2023年5月10日
    00
  • 【转】spdy协议

    【转】SPDY协议 今天我们要转发一篇来自互联网协议工程师的介绍SPDY协议的文章,希望给大家的网络技术学习带来一些帮助。 什么是SPDY协议? SPDY是一种由Google推出的基于TCP协议的网络传输协议,旨在缩短网页加载时间、减少网络延迟和优化用户的网络体验。SPDY代替HTTP协议进行数据传输,服务器和客户端之间的数据传输更快和可靠,同时能够减少网络…

    其他 2023年3月28日
    00
  • phpstorm怎么全局搜索

    以下是关于“PhpStorm如何进行全局搜索”的完整攻略: 步骤1:打开PhpStorm 首先,需要打开PhpStorm编辑器。 步骤2:打开全局搜索窗口 在PhpStorm中,可以使用以下快捷键打开全局搜索窗口: Windows和Linux系统:Ctrl + Shift + F macOS系统:Command + + F 也可以使用以下步骤打开全局搜索窗口…

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