Spring Cloud / Alibaba 微服务架构 | 2021年11月更文挑战(29)

307 阅读2分钟

这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

上篇文章中介绍了添加前缀的局部过滤器 PrefixPathGatewayFilterFacotry和去除前缀的局部过滤器 StripPrefixGatewayFilterFactory,这篇文章我们将自定义一个局部过滤器,用来校验Http请求头部中的Token。

自定义局部过滤器

1、创建对应的包和类

在e-commerce-gateway子模块下的com.sheep.ecommerce包下创建一个filter包。在包下创建HeaderTokenGatewayFilter类,即HTTP请求头部携带Token验证过滤器。

在filter包下再创建一个factory包,在包下创建HeaderTokenAbstractGatewayFilterFactory类。

2、编写过滤器 HeaderTokenGatewayFilter

对于局部过滤器我们需要去实现GatewayFilter和Ordered。代码如下:

public class HeaderTokenGatewayFilter implements GatewayFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String name = exchange.getRequest().getHeaders().getFirst("token");
        if ("hello".equals(name)) {
            return chain.filter(exchange);
        }
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE + 2;
    }
}

先看一下getOrder方法,return 最高优先级+2,因为order越高,优先级越低,所以我们加二,这样返回的就不是最高优先级了。

接下来再解读一下filter方法。首先是从 HTTP Header 中寻找 key 为 token, value 为 hello 的键值对。如果没有的话,就标记此次请求没有权限, 并结束这次请求。这样就保证了我们的这个请求里必须有"tooken":"hello"这样的键值对。

这样我们的过滤器实现就编写完了,接下来我们还要实现一个过滤器工厂GatewayFilterFactory。

3、编写过滤器工厂 HeaderTokenAbstractGatewayFilterFactory

要继承自AbstractGatewayFilterFactory,否则我们编写的局部过滤器是不生效的。需要的泛型我们定义为Object,接下来去重载里面的apply方法,直接return前面编写的HeaderTokenGatewayFilter方法即可。这样我们的局部过滤器代码编写就完成了。

4、配置

之前在配置网关的Nacos里有e-commerce-nacos-client这样一个路由配置:

{
  "id": "e-commerce-nacos-client",
  "predicates": [
    {
      "args": {
        "pattern": "/imooc/ecommerce-nacos-client/**"
      },
      "name": "Path"
    }
  ],
  "uri": "lb://e-commerce-nacos-client",
  "filters": [
    {
      "name": "HeaderToken"
    },
    {
      "name": "StripPrefix",
      "args": {
        "parts": "1"
      }
    }
  ]
}

其中filters就代表的是局部过滤器,因为全局过滤器不需要配置。filters里还有一个name是StripPrefix的过滤器,也就是之前我们有介绍过的,去除前缀的过滤器,parts为1代表去除一个前缀。

小结

简单来说,要实现一个自定义的局部过滤器,我们需要完成以下几件事:

1)实现GatewayFilter和Ordered

2)需要加到过滤器工厂里,并将工厂注册到Spring容器中(加上@Component注解)

3)在配置文件中进行配置,如果不配置则代表当前过滤器规则不会被启用