本文介绍了一些关于SpringCloud GateWay的基本概念与应用。

网关功能

  1. 身份认证,权限认证
  2. 服务路由,负载均衡
  3. 请求限流

搭建网关

  1. 添加依赖,nacos服务发现以及网关的依赖
<!--nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 编写路由配置以及nacos的地址
server:
port: 10010
spring:
application:
name: gateway

cloud:
nacos:
server-addr: localhost:8848

gateway:
routes:
- id: user-service # 路由的id,自定义,唯一即可
uri: lb://userservice # 路由的目标地址,lb是负载均衡的意思,后面跟着服务的名称
predicates:
- Path=/user/** # 路由断言,请求匹配规则,只要以user开头的就匹配

接着向网关所在端口发送请求信息,如http://localhost:10010/user/1,就可以得到userService服务的返回。

服务流程:

image-20230902161302541

路由断言工厂

Spring提供了多种断言工厂,除了Path用来限制路径以外,还可以限制ip,限制时间等

image-20230902162312852

详情实例见SpringCloudGateway文档路由断言工厂

路由过滤器

作用

对请求或者响应做加工处理,比如添加请求头

请求流程

客户端向网关发起请求,请求经过多层过滤器到达服务端,服务端的响应也会经过过滤器再返回给客户端

实例

假如想要给请求头添加一个token

spring:
application:
name: gateway

cloud:
nacos:
server-addr: localhost:8848

gateway:
routes:
- id: user-service # 路由的id,自定义,唯一即可
uri: lb://userService # 路由的目标地址,lb是负载均衡的意思,后面跟着服务的名称
predicates:
- Path=/user/** # 路由断言,请求匹配规则,只要以user开头的就匹配
filters:
- AddRequestHeader=token, xxx
default-filters:
- AddRequestHeader=token, xxx # 默认过滤器,会对所有请求都生效的过滤器

SpringCloud官网提供了31种过滤器,详细可以参考过滤器工厂

全局过滤器

定义一个类并且实现GlobalFilter接口,并且重写函数filter

@Order(-1)
@Component
public class AuthFilter implements GlobalFilter {

/**
*
* @param exchange 包含请求头,请求体的信息
* @param chain 过滤器链,若通过过滤器将其放行至下一个过滤器
* @return Mono类型的结果,若通过过滤器只需要返回chain.filter(exchange)即可
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求
ServerHttpRequest request = exchange.getRequest();
// 从请求中获取参数
MultiValueMap<String, String> params = request.getQueryParams();
// 获取具体参数
String authorization = params.getFirst("authorization");
// 判断身份信息
if("admin".equals(authorization)) {
return chain.filter(exchange);
}
// 身份验证失败,设置状态码
ServerHttpResponse response = exchange.getResponse();
// 参数是HttpStatus类型的,未登录状态码为401
response.setStatusCode(HttpStatus.UNAUTHORIZED);

return response.setComplete();
}
}

@Order(-1)注解是过滤器的执行顺序(或者说优先级),值越小优先级越高

@Component注解将过滤器注册为一个Bean

总结步骤:

  1. 实现GlobalFilter接口
  2. 添加@Order和@Component注解至类
  3. 编写过滤处理逻辑

过滤器执行顺序

每个过滤器都有一个order值,根据order值进行排序

GlobalFilter是由我们自定义order的值的

路由过滤器与默认过滤器的order值由spring决定,spring默认按照声明顺序从1开始递增

当order值一样时,会按照默认过滤器>路由过滤器>全局过滤器的顺序执行

跨域处理

只需要通过spring的配置就可以对网关的跨域进行处理

spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求,spring boot2.4以前的配置
- "http://localhost"
# allowedOriginPatterns: "*" # spring boot2.4以后的配置
allowCredentials: true # 是否允许带cookie
allowedMethods: # 跨域方法设置
- GET
- OPTIONS
- PUT
- DELETE
- POST
allowedHeaders: "*" # 允许携带的请求头信息
maxAge: 36000 # 跨域检测的有效期,单位s

题外话

接SpringCloud-Feign的题外话,果然有时候无法理解某个知识的时候,不妨继续学下去看看,后继拉动前驱了属于是