2026年告别登录中断:前端双 Token无感刷新

告别登录中断:前端双 Token无感刷新在前后端分离的项目中 为了安全 Token 通常会设置有效期 但如果 Token 过期时强制用户重新登录 会极大地破坏用户体验 如何做到在用户毫无察觉的情况下 自动完成 Token 的续期 本文将深度拆解 双 Token 无感刷新 的实现机制 举个简单例子 你正在某 App 编辑内容 中途切出几分钟 再切回来时 直接弹出登录页 提示

大家好,我是讯享网,很高兴认识大家。这里提供最前沿的Ai技术和互联网信息。



在前后端分离的项目中,为了安全,Token 通常会设置有效期。但如果 Token 过期时强制用户重新登录,会极大地破坏用户体验。如何做到在用户毫无察觉的情况下,自动完成 Token 的续期?本文将深度拆解 "双 Token 无感刷新" 的实现机制。

举个简单例子,你正在某 App 编辑内容,中途切出几分钟,再切回来时,直接弹出登录页,提示"登录已过期,请重新登录",这种场景很容易让用户流失。

传统的单 Token 方案存在一个两难境地:

  • 有效期过短:用户操作频繁,动不动就跳回登录页,用户体验极差。
  • 有效期过长:Token 一旦被截获,风险极高。

解决方案:双 Token 机制

  1. access_token:访问令牌。有效期短(如 1 小时),每次接口请求都携带,降低泄露风险。
  2. refresh_token :刷新令牌。有效期长(如 7 天),仅用于 access_token 过期时换取新令牌。

只要用户在 7 天内活跃过,系统就能通过 refresh_token 自动"续命",实现长效无感登录。


  1. 正常请求 :前端携带 access_token 访问。
  2. 触发过期 :后端返回 401 Unauthorized
  3. 判断逻辑
    • 如果是普通接口报 401:说明 access_token 失效,尝试刷新。
    • 如果是刷新接口 报 401:说明 refresh_token 也失效了,强制重新登录。
  4. 无感替换 :前端自动调用刷新接口,获取新 Token 覆盖本地存储,并重新发起之前失败的请求。

痛点:如果页面同时发出了 5 个请求,而此时 Token 刚好过期,会导致这 5 个请求同时触发"刷新 Token"的操作,造成资源浪费甚至后端异常。

解决策略

  • 状态锁 (refreshing) :记录当前是否正在刷新中。
  • 任务队列 (queue) :在刷新期间到达的请求,先暂存起来,不直接报错。
  • 批量回放:等待 Token 刷新成功后,依次执行队列里的请求,实现"无感"衔接。

以下是基于 Axios 的完整工程化实现:

 
     
    
       
GPT plus 代充 只需 145import axios, { AxiosRequestConfig } from 'axios'; 

interface PendingTask {

config: AxiosRequestConfig; resolve: Function; 

}

let refreshing = false; // 状态锁:标志是否正在刷新 Token let queue: PendingTask[] = []; // 请求队列:暂存 Token 刷新期间的请求

const axiosInstance = axios.create({

GPT plus 代充 只需 145baseURL: '/api' 

});

// 1. 请求拦截器:自动注入 Token axiosInstance.interceptors.request.use((config) => `;

} return config; 

});

// 2. 响应拦截器:处理 Token 过期 axiosInstance.interceptors.response.use(

GPT plus 代充 只需 145(response) => response, async (error) => { const { data, config } = error.response; // 情况 A:正在刷新 Token 中,将后续请求存入队列 if (refreshing) { return new Promise((resolve) => { queue.push({ config, resolve }); }); } // 情况 B:access_token 过期 (状态码 401 且非刷新接口本身) if (data.statusCode === 401 && !config.url.includes('/refresh')) ) => { resolve(axiosInstance(config)); }); queue = []; // 清空队列 // 执行当前触发刷新的那个请求 return axiosInstance(config); } } catch (err) { refreshing = false; queue = []; // 情况 C:refresh_token 也过期了,彻底清除登录态 localStorage.clear(); window.location.href = '/login'; return Promise.reject(err); } } return Promise.reject(error); } 

);

/

  • 刷新 Token 的异步方法 */ async function refreshToken() }); // 更新本地存储 localStorage.setItem(‘access_token’, res.data.accessToken); localStorage.setItem(‘refresh_token’, res.data.refreshToken); return res; }
 


  1. 并发请求的 Promise 挂起 :在 refreshingtrue 时,返回一个不带 resolvenew Promise 是关键,它能让 Axios 请求处于 pending 状态。
  2. 错误捕获refreshToken 接口本身报错(如 500 或 401)必须妥善处理,直接引导至登录页。
  3. 安全性 :普通项目中可以使用 localStorage,但在更高要求的项目中,建议配合 HttpOnly Cookie 存储 refresh_token 以防 XSS 攻击。
  4. 接口重定向陷阱:确保刷新 Token 的接口不会再次进入 401 拦截死循环。

小讯
上一篇 2026-03-17 21:40
下一篇 2026-03-17 21:38

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/243176.html