项目-网盘-网关-gateway

一 file-gateway/Tokenfilter

这个是定义了一个pring Cloud Gateway 应用中的全局过滤器

用于拦截请求并验证请求中的 JWT 令牌。

逐行注释下面的代码,一个token验证拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package top.quhailong.pan.file.gateway.filter;
@Component//将这个类注册成Spring bean
@RefreshScope// 允许在允许的时候刷新这个bean,通常用于动态更新配置属性
public class TokenFilter implements GlobalFilter, Ordered {
@Value("${filter-url}")
private String filterUrl;// 从nacos读取
//包含需要进行令牌验证的 URL 列表,从配置中注入






@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();//从exchange中获得当前请求的request
String uri = request.getURI().getPath();//从request中获得uri
List<String> uriList = Arrays.asList(filterUrl.split(","));//分割这个filterUrl,获取全部需要拦截的url列表
for (String filterUrl:uriList) {///如果当前这个url需要被拦截,就拦截下来,验证token,如果有token,且正确,就可以放行
if(uri.contains(filterUrl)){
return verifyToken(exchange, chain);
}
}
return chain.filter(exchange);
}


// 这里就是验证token方法
private Mono<Void> verifyToken(ServerWebExchange exchange, GatewayFilterChain chain) {
try {
ServerHttpRequest request;//尝试从请求的 Cookies 中获取名为 token 的令牌。
HttpCookie cookie = exchange.getRequest().getCookies().getFirst("token");//获得token,返回类型是cookie类型
String token = cookie.getValue();

//解析token(JWT)令牌,获得claim对象,这个对象是个啥。如果令牌失效就会返回错误的响应
Claims claims = JWTUtils.parseJWT(token, "nimadetou".getBytes());
//从 Claims 中提取 subject 并将其转换为 UserInfoDTO 对象。
String subject = claims.getSubject();
UserInfoDTO userinfo = JSONUtils.parseObject(subject, UserInfoDTO.class);



//将编码后的用户信息添加到请求头中,继续处理请求。
String operationInfo = URLEncoder.encode(JSONUtils.toJSONString(userinfo), StandardCharsets.UTF_8.toString());

// 把这个请求头放到request里面,然后继续向后面传递
request = exchange.getRequest().mutate().header("operationInfo", operationInfo).build();
return chain.filter(exchange.mutate().request(request).build());
} catch (Exception e) {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(RestAPIResultDTO.Error("token验证失败")).getBytes());
return response.writeWith(Flux.just(dataBuffer));
}
}

@Override
public int getOrder() {
return 0;//返回过滤器的顺序,数值越小优先级越高。这里返回 0 表示最高优先级。
}
}

二 JWT

JWT(JSON Web Token)是一种用于在各方之间作为 JSON 对象安全传输信息的紧凑且自包含的方式。JWT 的使用场景包括身份验证、信息交换等。

(1)JWT结构

包含三个部分:Header(头部)、Payload(负载)、Signature(签名)

1
Header.Payload.Signature

1. 头部

header通常包含两个部分,一个是令牌的类型(JWT)和签名算法(RSA,HMAC SH256)

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

2.Payload负载