Gateway--服务网关-过滤器

三个知识点:
1 作用: 过滤器就是在请求的传递过程中,对请求和响应做一些手脚
2 生命周期: Pre Post
3 分类: 局部过滤器(作用在某一个路由上) 全局过滤器(作用全部路由上)
在Gateway中, Filter的生命周期只有两个:“pre” 和 “post”。

  • PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
  • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTPHeader、收集统计信息和指标、将响应从微服务发送给客户端等。

Gateway 的Filter从作用范围可分为两种: GatewayFilter与GlobalFilter。

  • GatewayFilter:应用到单个路由或者一个分组的路由上。
  • GlobalFilter:应用到所有的路由上。

1 局部过滤器

局部过滤器是针对单个路由的过滤器。

1.1 内置局部过滤器

在SpringCloud Gateway中内置了很多不同类型的网关路由过滤器。具体如下:

内置局部过滤器的使用

server:
port: 7000
spring:
application:
 name: api-gateway
cloud:
 nacos:
  discovery:
   server-addr: localhost:8848
 gateway:
  discovery:
   locator:
    enabled: true
  routes:
   - id: product_route
    uri: lb://service-product
    order: 1
    predicates:
     - Path=/product-serv/**
    filters:
     - StripPrefix=1
     - SetStatus=2000 # 修改返回状态

1.2 自定义局部过滤器

第1步:在配置文件中,添加一个Log的过滤器配置

spring:
application:
 name: gateway
cloud:
 nacos:
  discovery:
   server-addr: 127.0.0.1:8848
 gateway:
  discovery:
   locator:
    enabled: true
  routes:
   - id: consumer
    order: -1
    uri: lb://consumer
    predicates:
     - Path=/consumer-serv/**
    filters:
     - StripPrefix=1
     - Log=true,false  # 控制日志是否开启

第2步:自定义一个过滤器工厂,实现方法

//自定义局部过滤器
@Component
public class LogGatewayFilterFactory
    extends AbstractGatewayFilterFactory<LogGatewayFilterFactory.Config> {
  //构造函数
  public LogGatewayFilterFactory() {
    super(LogGatewayFilterFactory.Config.class);
 }
  //读取配置文件中的参数 赋值到 配置类中
  @Override
  public List<String> shortcutFieldOrder() {
    return Arrays.asList("consoleLog", "cacheLog");
 }
  //过滤器逻辑
  @Override
  public GatewayFilter apply(LogGatewayFilterFactory.Config config) {
    return new GatewayFilter() {
      @Override
      public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
        if (config.isCacheLog()) {
            System.out.println("cacheLog已经开启了....");
       }
        if (config.isConsoleLog()) {
          System.out.println("consoleLog已经开启了....");
       }
        return chain.filter(exchange);
     }
   };
 }
  //配置类 接收配置参数
  @Data
  @NoArgsConstructor
  public static class Config {
    private boolean consoleLog;
    private boolean cacheLog;
 }
}

第3步:启动测试

2 全局过滤器

        全局过滤器作用于所有路由, 无需配置。通过全局过滤器可以实现对权限的统一校验,安全性验证等功能。

2.1 内置全局过滤器

SpringCloud Gateway内部也是通过一系列的内置全局过滤器对整个路由转发进行处理如下:

2.2 自定义全局过滤器

        内置的过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们自己编写过滤器来实现的,那么我们一起通过代码的形式自定义一个过滤器,去完成统一的权限校验。
        开发中的鉴权逻辑:

  • 当客户端第一次请求服务时,服务端对用户进行信息认证(登录)
  • 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证
  • 以后每次请求,客户端都携带认证的token
  • 服务端对token进行解密,判断是否有效。

        如上图,对于验证用户是否已经登录鉴权的过程可以在网关统一检验。
        检验的标准就是请求中是否携带token凭证以及token的正确性。
        下面的我们自定义一个GlobalFilter,去校验所有请求的请求参数中是否包含“token”,如何不包含请求参数“token”则不转发路由,否则执行正常的逻辑。

package com.itheima.filters;
//自定义全局过滤器需要实现GlobalFilter和Ordered接口
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
  //完成判断逻辑
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain
chain) {
    String token = exchange.getRequest().getQueryParams().getFirst("token");
    if (StringUtils.isBlank(token)) {
      System.out.println("鉴权失败");
      exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
      return exchange.getResponse().setComplete();
   }
    //调用chain.filter继续向下游执行
    return chain.filter(exchange);
 }
 
  //顺序,数值越小,优先级越高
  @Override
  public int getOrder() {
      return 0;
 }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chuxuezhe_987

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值