1、过滤器(Filter)增强分析
1.1 概述
过滤器(Filter)就是在请求传递过程中,对请求和响应做一个处理。Gateway 的Filter从作用范围可分为两种:GatewayFilter与GlobalFilter。其中:
- GatewayFilter:应用到单个路由或者一个分组的路由上。
- GlobalFilter:应用到所有的路由上。
1.2 局部过滤器设计及实现
在SpringCloud Gateway中内置了很多不同类型的网关路由过滤器
案例分析:
基于AddRequestHeaderGatewayFilterFactory,为原始请求添加Header。
1.2.1 X-Request-Foo案例说明
说明:原始请求添加名为 X-Request-Foo ,值为 Bar 的请求头:
1.2.2 修改配置文件
1.2.3 修改代码
1.2.4 测试结果
1.2.5 基于AddRequestParameterGatewayFilterFactory,
说明:为原始请求添加请求参数及值,原始请求添加名为foo,值为bar的参数,即:foo=bar,
1.2.6 修改配置文件
1.2.7 修改代码
1.2.8 测试结果
2、全局过滤器设计及实现
2.1 概述
全局过滤器(GlobalFilter)作用于所有路由, 无需配置。在系统初始化时加载,并作用在每个路由上。通过全局过滤器可以实现对权限的统一校验,安全性验证等功能。一般内置的全局过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们 自己编写过滤器来实现的,那么我们一起通过代码的形式自定义一个过滤器,去完成统一的权限校验。 例如,当客户端第一次请求服务时,服务端对用户进行信息认证(登录) 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证 以后每次请求,客户端都携带认证的token 服务端对token进行解密,判断是否有效。
2.2 全局过滤器入门案例
2.2.1 创建AuthGatewayFilter
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthGatewayFilter implements GlobalFilter, Ordered
{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
System.out.println("路径:" + path);
String username = request.getQueryParams().getFirst("username");
if (!"admin".equals(username))
{
System.out.println("认证失败");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder()
{
return Ordered.HIGHEST_PRECEDENCE;
}
}
2.2.2 测试结果
说明:启动Gateway服务,假如在访问的url中不带“username=admin”这个参数,会出现异常
3、小结面试
- 网关过滤器的作用是什么?(对请求和响应数据做一个预处理)
- 网关过滤器的类型有哪些?(局部过滤器,全局过滤器)
- 如何理解局部过滤器?(针对具体链路的应用的过滤器,需要进行配置)
- 你了解哪些局部过滤器?
- 如何理解全局过滤器?(作用于所有请求链路)
- 如何自己定义全局过滤器?(直接或间接实现GlobalFilter接口)
- 假如现在让你进行平台的网关自研设计,你可以吗?(可以)
3.1 作业说明
3.1.1 文件上传
说明:尝试在文件上传服务上创建网关项目,客户端请求直接请求网关实现文件上传.
3.1.2 创建Sca-Resource-Gateway
3.1.3 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
3.1.4 编辑bootstrap.yml配置文件
server:
port: 9000
spring:
application:
name: sca-resource-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yml
gateway:
discovery:
locator:
enabled: true
routes:
- id: router01
uri: lb://sca-resource
predicates:
- Path=/sca/resource/upload/**
filters:
- StripPrefix=1
3.1.5 创建启动类
3.1.6 配置全局跨域
说明:前端JS发起的请求为ajax请求
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class CorsFilterConfig
{
@Bean
public CorsWebFilter corsWebFilter()
{
//1.构建基于url方式的跨域配置
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//2.进行跨域配置
CorsConfiguration config=new CorsConfiguration();
//2.1允许所有ip:port进行跨域
config.addAllowedOrigin("*");
//2.2允许所有请求头跨域
config.addAllowedHeader("*");
//2.3允许所有请求方式跨域:get,post,..
config.addAllowedMethod("*");
//2.4允许携带有效cookie进行跨域
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
3.1.7 启动服务测试
说明:一次启动Sca-Resource,Sca-Resource-UI,Sca-Resource-Gateway
测试结果: