Token无感刷新机制能静默更新访问凭证,确保用户持续保持登录状态。本文将详细解析客户端与服务器端的实现方案,并针对常见问题给出解决方案。
通过短期token进行权限验证,配合长期refreshToken实现凭证更新,这种机制在实际应用中会遇到几个关键问题:
核心思路:通过服务器网关拦截请求并校验token有效性
基于SpringBoot3+Java17环境,继承GlobalFilter实现过滤逻辑
@Component
public class MyAccessFilter implements GlobalFilter, Ordered
{
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String uri = request.getURI().getPath();
HttpMethod method = request.getMethod();
// OPTION直接放行
if(method.matches(HttpMethod.OPTIONS.name()))
return chain.filter(exchange);
//登录请求直接放行
if(SecurityAccessConstant.REQUEST_LOGGING_URI.equals(uri) && method.matches(HttpMethod.POST.name()))
return chain.filter(exchange);
//获取token
String token = JWTHelper.getToken(request.getHeaders().getFirst(SecurityAccessConstant.HEADER_NAME_TOKEN));
if(null != token){
//判断token是否过时
if(!JWTHelper.isOutDate(token)){
return chain.filter(exchange);
}else{
if(!SecurityAccessConstant.REQUEST_REFRESH.equals(uri)) //当前不是刷新请求可以刷新返回的状态码就是511
return ResponseUtils.out(exchange , ResultData.fail(ResultCodeEnum.NEED_TO_REFRESH_TOKEN.getCode(),
ResultCodeEnum.NEED_TO_REFRESH_TOKEN.getMessage()));
//当前是刷新请求 但refreshToken都过期了,即刷新不支持
return ResponseUtils.out(exchange , ResultData.fail(ResultCodeEnum.RC401.getCode(), ResultCodeEnum.RC401.getMessage()));
}
}
return ResponseUtils.out(exchange , ResultData.fail(ResultCodeEnum.RC401.getCode(), ResultCodeEnum.RC401.getMessage()));
}
@Override
public int getOrder() {
//数值越小 优先级越高
return Ordered.LOWEST_PRECEDENCE;
}
}
通过响应状态码判断执行不同操作:
使用原生axios发起异步请求,避免循环调用问题
引入定时检查机制,在token临近过期时主动刷新
通过setInterval定期检查token有效期
在发放token时附带过期时间信息
通过网关拦截并异步刷新token的方案
本文详细解析了无感刷新token的实现方案,针对不同场景给出了具体实现方法,帮助开发者根据实际需求选择最佳实践方案。