Gateway 作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作往往是通过网关提供的过滤器来实现 的。

Gateway 自带过滤器有几十个,常见自带过滤器有:

AddRequestHeader: 对匹配上的请求加上Header

AddRequestParameters :对匹配上的请求路由添加参数

AddResponseHeader :对从网关返回的响应添加Header

StripPrefifix :对匹配上的请求路径去除前缀

1.使用Gateway自带的过滤器

使用时只需在application.yml或者application.xml中配置即可

下图配置了一个路由去除前缀的过滤器( - StripPrefix=1表示去除第一个前缀,如

http:127.0.0.1:8080/api/user/2,此过滤器会把此路由改为http:127.0.0.1:8080/user/2 );

spring:
  cloud:
    gateway:
      routes:
        #路由Ip,可以任意设置
        - id: user-service-route
          #代理的服务地址
          uri: lb://billManager-service
          #断言
          predicates:
            - Path=/**
           #使用自带的过滤器
          filters:
            - StripPrefix=1

配置全局默认过滤器:

这些自带的过滤器可以将这些过滤器配置成不只是针对某个路由;而 是可以对所有路由生效,也就是配置默认过滤器:

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        #路由Ip,可以任意设置
        - id: user-service-route
          #代理的服务地址
          #uri: http://127.0.0.1:9091
          uri: lb://user-service
          #断言
          predicates:
            - Path=/**
          filters:
            - StripPrefix=1
           #配置默认全局过滤器
          default-filters:
             - AddResponseHeader=X-Response-Foo,Bar

2.使用自定义的过滤器:

AbstractGatewayFilterFactory 类,且命名需要参照gateway自带过滤器,即:name+GatewayFilterFactory,如UserGatewayFilterFactory。具体写法可参照自带的过滤器。

/**
 * 自定义过滤器:获取请求路径中的属性的值
 */
@Component
public class UserGatewayFilterFactory extends AbstractGatewayFilterFactory<UserGatewayFilterFactory.Config> {

    public UserGatewayFilterFactory() {
        super(Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Arrays.asList("param");
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            if (request.getQueryParams().containsKey(config.param)) {
                request.getQueryParams().get(config.param).forEach((v) -> {
                    System.out.printf("--局部过滤器--获得参数 %s = %s ----", config.param, v);
                });
            }

            return chain.filter(exchange); //执行请求
        };
    }


    //读取过滤器配置的参数
    public static class Config {
        //对应配置过滤器的时候读取指定的参数
        private String param;

        public String getParam() {
            return param;
        }

        public void setParam(String param) {
            this.param = param;
        }
    }

}

在 application.yml或者application.xml中配置

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        #路由Ip,可以任意设置
        - id: user-service-route
          #代理的服务地址
          uri: lb://user-service
          #断言
          predicates:
            - Path=/**
          filters:
            - MyParam=name

3.全局过滤器

GlobalFilter 是用来定义全局过滤器的接口,通过实现GlobalFilter接口可以实现各种自定义过滤器,无须在配置文件种配置。有多个拦截器时通过Ordered接口实现getOrder()方法来指定执行顺序,返回值越小执行顺序越靠前。

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("全局部过滤器定义=--------------");
        //判断请求头是否有user参数的值
        String user = exchange.getRequest().getHeaders().getFirst("user");
        if (StringUtils.isBlank(user)){
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            //直接结束
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //数字越小,越先执行
        return 1;
    }
}