一聚教程网:一个值得你收藏的教程网站

热门教程

SpringBoot中无感刷新token的实践方案

时间:2026-05-29 18:00:01 编辑:袖梨 来源:一聚教程网

Token无感刷新机制能静默更新访问凭证,确保用户持续保持登录状态。本文将详细解析客户端与服务器端的实现方案,并针对常见问题给出解决方案。

前言

通过短期token进行权限验证,配合长期refreshToken实现凭证更新,这种机制在实际应用中会遇到几个关键问题:

  1. Q1: 该机制更适合在服务端还是客户端实现?
  2. Q2: 过期token无法解析时,如何获取其中的过期时间?
  3. Q3: 如何实现请求重发并将结果返回原调用方?

一、客户端实现

1.1 初始版本

核心思路:通过服务器网关拦截请求并校验token有效性

  1. 若token过期则返回特定状态码通知客户端
  2. 若token有效则继续处理原请求

1.1.1 服务器端gateway实现拦截器

基于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;
    }
}

1.1.2 axios拦截器

通过响应状态码判断执行不同操作:

  1. 401状态码:清空用户数据并跳转登录页
  2. 511状态码:使用refreshToken发起刷新请求

1.1.3 refresh刷新方法实现

使用原生axios发起异步请求,避免循环调用问题

1.2 改进版本

引入定时检查机制,在token临近过期时主动刷新

1.2.1 定时器类实现

通过setInterval定期检查token有效期

1.3 最终定时器版本

1.3.1 服务端调整

在发放token时附带过期时间信息

2. 服务器端实现

通过网关拦截并异步刷新token的方案

3. 方案选择

3.1 服务端优势

  1. 安全性更高
  2. 减少客户端复杂度
  3. 便于集中管理

3.2 客户端优势

  1. 响应更及时
  2. 支持离线场景
  3. 减轻服务端压力

本文详细解析了无感刷新token的实现方案,针对不同场景给出了具体实现方法,帮助开发者根据实际需求选择最佳实践方案。

热门栏目