Vue3 + Axios双Token刷新解决方案

在现代前端开发中,使用 API 进行数据交互时,我们常常会遇到身份认证的问题。为了提高安全性,许多应用采用了Token 机制,如JWT(JSON Web Token) 来管理用户的身份状态。本文将介绍如何在 Vue3 项目中使用 Axios 实现双 Token 刷新机制,确保用户体验流畅的同时提高安全性。

前置条件

  1. 本文只针对Vue3前端所编写的双Token刷新解决方案,关于Spring Cloud微服务项目的双Token刷新实现,请参考:Spring Cloud + JWT实现双Token刷新
  2. 关于Vue3项目的搭建,请参考:Vite 创建 Vue3 + TS 项目
  3. 本文将通过封装Axios的方式,让前端实现无感刷新Token,关于Axios的封装,请参考:Vue3项目基于Axios封装request请求

刷新机制

在完成上述步骤后,我们就可以开始对前端项目进行操作了。但首先,我们需要了解到双Token刷新的机制:

在使用 Token 认证时,我们通常会使用两种Token:

  1. **Access Token:**用于身份验证,通常时效较短(如 10 分钟)。
  2. Refresh Token:用于获取新的 Access Token,时效较长(如 7 天至几个月)。

Access Token 过期时,我们可以使用Refresh Token 来请求新的Access Token,而不是要求用户重新登录。通过这种方式,用户的体验将更加平滑。

但是,这里是博主自己写的后端,博主的服务端在双Token刷新机制上的原理跟上述是一样的, 不同的是,博主在生成Token的时候,并没有将Refresh Token 返回给前端,而是跟UserId 一起以键值对的形式存储在了Redis中。

在客户端Access Token 过期后,直接根据Base64 解析出Access Token 载荷中的UserId ,然后根据这个UserId 查询存储在Redis 中的Refresh Token ,如果这个Refresh Token 有效且是合法的,那么我们就根据之前Access Token 载荷中的信息重新生成一个Access Token 返回给客户端,以此来达到刷新Token的目的。

根据以上Token 刷新机制,我们在Vue3 前端代码中,可以给出一个无感刷新Token的思路:

  • 如果Access Token 过期,那么我们可以通过Axios 的响应拦截器获取到新的Access Token
  • 如果获取到的这个Access Token存在且不为空,我们可以重新发送原始请求

代码实现

javascript 复制代码
// 添加响应拦截器
service.interceptors.response.use(

	async (response) => {

        // 判断是否有新的Token
		if (response.data.ACCESS_TOKEN) {
            // 将服务端返回的新Token存储到Session中
			Session.set('token', response.data.ACCESS_TOKEN);
			// 重新发送原始请求
            const config = response.config;
            try {
                const newResponse = await service.request(config);
                return newResponse;
            } catch (error) {
                return Promise.reject(error);
            }
		}

		// 对响应数据做点什么
		const res = response.data;
		if (res.code && res.code !== 0) {
			// `token` 过期或者账号已在别处登录
			if (res.code === 401 || res.code === 4001) {
				Session.clear(); // 清除浏览器全部临时缓存
				window.location.href = '/'; // 去登录页
				ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
					.then(() => { })
					.catch(() => { });
				return Promise.reject(service.interceptors.response);
			} else {   // 如果响应中有新的 token,则更新 Session 中的 token

				return res;
			}

		} else {
			return res;
		}
	},
	(error) => {
		// 对响应错误做点什么
		if (error.message.indexOf('timeout') != -1) {
			ElMessage.error('网络超时');
		} else if (error.message == 'Network Error') {
			ElMessage.error('网络连接错误');
		} else {
			if (error.response.data) ElMessage.error(error.response.statusText);
			else ElMessage.error('接口路径找不到');
		}
		return Promise.reject(error);
	}
);

检验真理

如图,当Token过期时,我们访问这个查询接口时,Axios进行了两次接口调用

第一次调用这个查询接口时,我们的Token失效了,拿到了服务端给的新的Token

然后,根据我们之前在Axios响应拦截器中的代码逻辑,它在将这个新的Token存储到Session中后,又重新发送了一次原始请求

相关推荐
tiandyoin1 小时前
Notepad++ 修改 About
前端·notepad++·html5
职场人参1 小时前
怎么将几个pdf合成为一个?把几个PDF合并成为一个的8种方法
前端
二豆是富婆2 小时前
vue3 element plus table 滚动到指定位置
javascript·vue.js·elementui
学前端搞口饭吃2 小时前
vue2-ssr从vue-cli搭建项目改造服务端渲染+打包上线部署
前端·javascript·vue.js
鱼在在3 小时前
uni-app 聊天界面滚动到消息底部
javascript·uni-app·vue
CRMEB系统商城3 小时前
前端项目node版本问题导致依赖安装异常的处理办法
前端
anyup_前端梦工厂3 小时前
Vue 中常用的基础指令
前端·javascript·vue.js
coderYYY3 小时前
CSS实现原生table可拖拽调整列宽
前端·css·html·css3
计算机学姐3 小时前
基于python+django+vue的农业管理系统
开发语言·vue.js·后端·python·django·pip·web3.py
计算机程序设计开发3 小时前
小说阅读网站登录注册搜索小说查看评论前后台管理计算机毕业设计/springboot/javaWEB/J2EE/MYSQL数据库/vue前后分离小程序
数据库·vue.js·spring boot·java-ee·课程设计·计算机毕业设计·数据库管理系统