当前位置: 首页 > news >正文

前端无感刷新 Token 的 Axios 封装方案

在现代前端应用中,基于 Token 的身份验证已成为主流方案。然而,Token 过期问题常常困扰开发者 —— 如何在不打断用户操作的情况下自动刷新 Token,实现 "无感刷新" 体验?本文将详细介绍基于 Axios 的解决方案。

什么是无感刷新 Token?

无感刷新 Token 指的是当用户访问需要身份验证的接口时,若当前 Token 已过期,系统自动使用刷新 Token 获取新的访问 Token,并用新 Token 重新发起原请求,整个过程对用户完全透明,不影响用户操作流程。

实现思路
  1. 拦截所有请求,在请求头中自动添加 Token
  2. 拦截响应,检测 Token 过期错误
  3. 当 Token 过期时,使用刷新 Token 获取新的访问 Token
  4. 用新 Token 重新发起原请求,并将结果返回给用户
  5. 处理并发请求问题,避免多次刷新 Token

代码

auth.js:

// Token存储工具函数// 存储Token到本地存储
export const setToken = (token) => {localStorage.setItem('accessToken', token);
};// 从本地存储获取Token
export const getToken = () => {return localStorage.getItem('accessToken');
};// 存储刷新Token到本地存储
export const setRefreshToken = (refreshToken) => {localStorage.setItem('refreshToken', refreshToken);
};// 从本地存储获取刷新Token
export const getRefreshToken = () => {return localStorage.getItem('refreshToken');
};// 清除所有Token
export const removeTokens = () => {localStorage.removeItem('accessToken');localStorage.removeItem('refreshToken');
};

request.js:

import axios from 'axios';
import { getToken, getRefreshToken, setToken, removeTokens } from './auth';// 创建axios实例
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // 基础URLtimeout: 5000 // 请求超时时间
});// 是否正在刷新的标记
let isRefreshing = false;
// 存储等待刷新的请求队列
let requests = [];// 请求拦截器
service.interceptors.request.use(config => {// 从本地存储获取Tokenconst token = getToken();// 如果Token存在,则添加到请求头if (token) {config.headers['Authorization'] = `Bearer ${token}`;}return config;},error => {// 请求错误处理return Promise.reject(error);}
);// 响应拦截器
service.interceptors.response.use(response => {// 成功响应处理return response.data;},async error => {const originalRequest = error.config;// 如果不是401错误或者已经重试过,则直接返回错误if (error.response?.status !== 401 || originalRequest._retry) {return Promise.reject(error);}// 如果正在刷新Token,则将请求加入队列if (isRefreshing) {try {// 等待刷新Token完成const token = await new Promise(resolve => {requests.push(token => {resolve(token);});});// 使用新Token重新发起请求originalRequest.headers['Authorization'] = `Bearer ${token}`;return service(originalRequest);} catch (err) {return Promise.reject(err);}}// 标记为正在刷新TokenoriginalRequest._retry = true;isRefreshing = true;try {// 调用刷新Token接口const refreshToken = getRefreshToken();const { data } = await axios.post(`${process.env.VUE_APP_BASE_API}/refresh-token`, {refreshToken});// 存储新的TokensetToken(data.token);// 执行队列中的请求requests.forEach(cb => cb(data.token));requests = [];// 重新发起原请求originalRequest.headers['Authorization'] = `Bearer ${data.token}`;return service(originalRequest);} catch (refreshError) {// 刷新Token失败,清除Token并跳转登录页removeTokens();window.location.href = '/login';return Promise.reject(refreshError);} finally {// 重置刷新状态isRefreshing = false;}}
);export default service;

http://www.dtcms.com/a/342900.html

相关文章:

  • Github 下载加速--2025-08-21 亲测好用
  • 神经网络(Neural Network, NN)
  • gemini cli 用命令行玩转 AI 多模态开发
  • 网络安全大模型测试指标体系设计思路
  • 我与 ChatGPT 5:一段时间的深度编程体验与全栈评测
  • Zabbix状态图标灯显示
  • K8s部署dashboard平台和基本使用
  • MySQL:MVCC机制及其在Java秋招中的高频考点
  • AutoTrack-IR-DR200平台的构建与实现过程
  • python采集义乌购(yiwugo)商品详情API接口,json数据返回
  • 透射TEM 新手入门:快速掌握核心技能
  • 【每日一道算法题 day5】盛最多水的容器 (Container With Most Water) - LeetCode 题解
  • 深度学习之NLP基础
  • 【React】tab切换功能和排序实现,classnames工具优化类名控制
  • Java基础环境jdk和maven安装及配置+开源项目下载及编译打包教程
  • Flutter如何通过GlobalKey调用组件内的方法
  • 微服务的编程测评系统13-我的竞赛列表-elasticSearch
  • 与H5交互,与flutter的交互
  • 求解三位数
  • 深度解析DeepSeek V3.1 :6850 亿参数开源模型如何以 71.6% 编码得分、68 倍成本优势重构全球 AI 竞争格局
  • 使用postman模拟http请求webservice服务
  • 企业如何用外贸进销存系统管理好库存产品?
  • Docker安装elasticsearch以及Kibana、ik分词器
  • 从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(十三)
  • 相似图像处理程序
  • mac的m3芯使用git
  • 1.2 亿篇论文数据集,多学科学术语料库,涵盖医学、化学、生物学、人文、物理、工程、数学、生态、经济与计算机科学,用于 NLP、知识图谱与大模型训
  • 意象驱动的深层语义:感知认知统一对自然语言处理与知识图谱的影响
  • 数据结构——二叉树(Binary Tree)
  • 自然语言处理NLP L4: 高级语言模型——四种泛化平滑方式