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;
}
}