网关组件
# Gateway
Maven依赖
<!-- Gateway网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
配置文件
spring:
cloud:
gateway: # 网关配置
routes: # 路由配置
- id: user-service # 用户模块的路由
predicates: # 断言规则
- Path=/user/** # 所有以/user路径开头的请求
uri: lb://userservice # 负载均衡到userservice服务
filters: # 过滤器
- AddRequestHeader=aaa, 123456
- id: order-service
predicates:
- Path=/order/**
uri: lb://orderservice
default-filters: # 通用过滤器
- AddRequestHeader=aaa, 123456
globalcors: # 跨域请求处理
add-to-simple-url-handler-mapping: true # 允许OPTIONS预检请求
corsConfigurations:
'[/**]': # 针对请求地址配置
alloweOrigins: # 允许跨域的URL
- "http://www.hanzhe.site"
- "https://www.hanzhe.site"
allowedMethods: # 允许跨域的请求方法
- "OPTIONS"
- "GET"
- "POST"
- "PUT"
- "DELETE"
allowedHeaders: "*" # 允许携带哪些请求头
allowedCredentials: true # 是否允许携带Cookie
maxAge: 360000 # 预检请求有效期
# 可选择启用Gateway的路由日志,适用于路由排错
logging:
level:
org.springframework.cloud.gateway: trace
org.springframework.cloud.loadbalancer: trace
org.springframework.web.reactive: trace
# 断言工厂
名称 | 作用 | 示例 |
---|---|---|
After | 对指定时间之后的请求生效 | - After=2024-01-01T00:00:00.000[America/Denver] |
Before | 对指定时间之前的请求生效 | - Before=2023-01-01T00:00:00.000+08:00[Asia/Shanghai] |
Between | 对两个时间点之间的请求生效 | - Between=时间, 时间 |
Cookie | 请求必须包含某个Cookie | - Cookie=ch,sessionid |
Header | 请求必须包含某个Header | - Header=X-Request-Id,token |
Host | 请求必须访问某个域名 | - Host=www.hanzhe.site,*.baidu.com |
Method | 请求必须是指定方法 | - Method=GET,POST |
Path | 请求路径必须符合规则 | - Path=/user/**,/guest/** |
Query | 请求必须包含指定参数 | - Query=name,email |
RemoteAddr | 请求者IP必须是指定范围 | - RemoteAddr=192.168.1.1/24 |
# 过滤器
三种过滤器级别:
- 路由过滤器,配置文件中 routes 级别下的都是路由过滤器
- 默认过滤器,配置文件中与 routes 同级别的
default-filters
,对所有路由生效 - 自定义过滤器,自己创建的
GlobalFilter
的实现类
过滤器执行顺序:
- 过滤器执行顺序是通过 order 进行排序,order 值越小,就越优先执行
- 配置文件中按照编写顺序,从上到下从 1 开始累加,每个路由,默认,自定义都有自己的排序
- order 值相同的情况下,默认> 路由 > 自定义
名称 | 作用 | 示例 |
---|---|---|
AddRequestHeader | 在请求中添加请求头 | AddRequestHeader=token |
RemoveRequestHeader | 在请求中删除请求头 | RemoveRequestHeader=token |
AddResponseHeader | 在响应中添加响应头 | AddResponseHeader=token |
RemoveResponseHeader | 在响应中删除响应头 | RemoveResponseHeader=token |
RequestRateLimiter | 限制请求流量 | |
RewritePath | 请求路径重写 | RewritePath=/user/?(?<segment>.*),/$\{segment} |
StripPrefix | 去除请求路径N级前缀 | StripPrefix=1 |
自定义过滤器
自定义全局过滤器,配置完成后会自动在全局生效
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取Request和Response对象
ServerHttpRequest req = exchange.getRequest();
ServerHttpResponse resp = exchange.getResponse();
// 在请求头中获取Token
String token = null;
List<String> tokenHeaders = req.getHeaders().get("authorization");
if (CollUtil.isNotEmpty(tokenHeaders)) {
token = CollUtil.getFirst(tokenHeaders);
}
// 校验并解析Token
Long userId = String.valueOf(jwtTool.parseToken(token));
// 传递用户信息
ServerWebExchange exchange2 = exchange.mutate().request(request -> request.header("user-info", userInfo)).build();
// 放行
return chain.filter(exchange2);
}
@Override
public int getOrder() {
return 0;
}
}
自定义网关过滤器比较自由,可以自主选择网关过滤或者全局过滤,遵循***GatewayFilterFactory
的命名规则,***
就可以直接在配置文件中使用,例如:- Token=true
@Component
public class TokenGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenGatewayFilterFactory.Config> {
public TokenGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// 只有明确指定了enable为true时,TokenGatewayFilterFactory才会执行过滤
if (config.isEnable()) {
List<String> token = exchange.getRequest().getQueryParams().get("token");
if (CollUtil.isEmpty(token)) throw new RuntimeException("令牌不能为空");
if (!TokenUtil.verify(token)) throw new RuntimeException("不合法的令牌");
}
// 放行请求
return chain.filter(exchange);
};
}
@Override
public List<String> shortcutFieldOrder() {
// 接收参数的顺序
return CollUtil.newArrayList("enable");
}
@Getter
@Setter
public static class Config {
/** 都能接收哪些参数 */
private boolean enable;
}
}