目录
2.1 一般的做法是在公共的module中添加,此处示例为common 公共配置module中添加
4.2 (网关-微服务)微服务拦截器拦截从网关发送过来的请求,从请求头中获取到用户信息后会通过ThreadLocal保存使用。
4.3 (微服务-微服务)微服务若再向其他微服务发起请求,则通过OpenFeign提供的RequestInterceptor拦截发出的请求,并进行将用户信息保存在请求头中的操作。
1 网关获取用户校验信息并保存至请求头(前端-网关)
思路是添加过滤器,网关过滤器有两种,分别是:
GatewayFilter:路由过滤器,作用于任意指定的路由;默认不生效,要配置到路由后生效。
GlobalFilter:全局过滤器,作用范围是所有路由;声明后自动生效。
两种过滤器的过滤方法签名完全一致。
此处以GlobalFilter为例实现网关登录校验
首先定义定义全局过滤器并实现两个接口,特别说明Ordered接口是改变其权重,提升其优先级别,保证在pre阶段先执行(若不懂pre阶段请看3 网关处理流程)。过滤器定义逻辑如下,拦截符合条件的请求(常见的是需要登录的请求)-> 登录校验 -> 将信息存入上下文请求头中
@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(AuthProperties.class)
public class AuthGlobalFilter implements GlobalFilter, Ordered {
private final AuthProperties authProperties; //配置文件类,开发无需登录路径
private final JwtTool jwtTool; //jwt工具类
private final AntPathMatcher antPathMatcher = new AntPathMatcher(); //路径匹配
//工具类
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 其中exchange 为上下文,在过滤器链路中负责传递信息
// 1.获取request 请求
ServerHttpRequest request = exchange.getRequest();
// 2.判断是否需要做登陆拦截
if(isExclude(request.getPath().toString())){
// 放行
return chain.filter(exchange);
}
// 3.获取token
HttpHeaders headers = request.getHeaders();
String token = null;
List<String> authorization = headers.get("authorization");
if(authorization !=null && !authorization.isEmpty()){
token = authorization.get(0);
}
// 4.校验并解析token
Long userId = null;
try {
userId = jwtTool.parseToken(token);
}catch (UnauthorizedException e){
// 拦截
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
// TODO 5.传递用户信息
String userInfo= userId.toString();
//存入上下文
ServerWebExchange swe = exchange.mutate()
.request(builder -> builder.header("user-info", userInfo))
.build();
// 6.放行 传入下一层过滤器中
return chain.filter(swe);
}
//工具方法,用来判断是否包含在公共开放的路径中
private boolean isExclude(String path) {
for (String pathPattern: authProperties.getExcludePaths()) {
if (antPathMatcher.match(pathPattern,path)){
return true;
}
}
return false;
}
// 设置在过滤器中的级别,数字越小,级别越高,在pre过程中先执行
@Override
public int getOrder() {
return 0;
}
}
关建步骤在5,通过5将用户信息存入上下文中,然后放在请求头中。即可完成将获取用户校验信息并存入请求头中。
2 微服务获取网关中的用户校验信息(网关-微服务)
获取方法是加拦截器,加在每一个微服务