Vue如何优雅处理Token过期并自动续期
作者:江城开朗的豌豆
大家好,干了6年前端,和Token斗智斗勇了不知道多少回。最烦的就是用户正填着表单呢,突然跳登录页——Token过期了!今天就跟大家聊聊如何优雅处理Token过期,甚至让它自动续期,让用户无感知!
一、Token过期,用户的噩梦
想象一下:
- 用户填了半小时的报销单,点击提交—— “登录失效,请重新登录”
- 购物车选了半天,结算时——跳转登录页
血压直接拉满,用户体验直接崩盘!
常见处理方式(但不够优雅)
- 粗暴型:Token过期直接跳登录页(用户骂娘)
- 提醒型:弹窗提示“登录已过期”(用户还是得手动操作)
- 轮询检查型:定时检查Token是否快过期(浪费请求)
但今天我要讲的是更高级的玩法——无感知自动续期!
二、Token自动续期方案
1. 方案核心思路
- 短期Token(Access Token) :用来做日常请求(比如2小时过期)
- 长期Token(Refresh Token) :用来换新Token(比如7天过期)
流程:
- 用户登录,拿到
access_token和refresh_token access_token过期后,用refresh_token去换新的- 如果
refresh_token也过期了,才让用户重新登录
2. 前端如何实现
(1)Axios 拦截器处理过期
// 请求拦截
axios.interceptors.request.use(config => {
const accessToken = localStorage.getItem('access_token')
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`
}
return config
})
// 响应拦截
axios.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config
// 如果是401(Token过期)且未重试过
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
try {
// 用 refresh_token 换新的 access_token
const res = await axios.post('/refresh-token', {
refresh_token: localStorage.getItem('refresh_token')
})
const { access_token, refresh_token } = res.data
localStorage.setItem('access_token', access_token)
localStorage.setItem('refresh_token', refresh_token)
// 重新发之前的请求
originalRequest.headers.Authorization = `Bearer ${access_token}`
return axios(originalRequest)
} catch (refreshError) {
// refresh_token 也过期了,跳登录页
window.location.href = '/login'
}
}
return Promise.reject(error)
}
)
(2)提前续期(更丝滑)
如果等Token完全过期再换新,用户可能会遇到卡顿。更优解是在Token快过期时提前续期:
// 检查Token剩余时间
function checkTokenExpiry() {
const token = localStorage.getItem('access_token')
if (!token) return false
const payload = JSON.parse(atob(token.split('.')[1])) // 解析JWT
const expiresIn = payload.exp * 1000 - Date.now()
// 如果还剩5分钟过期,就续期
if (expiresIn < 5 * 60 * 1000) {
refreshToken()
}
}
// 定时检查(每10分钟一次)
setInterval(checkTokenExpiry, 10 * 60 * 1000)
三、安全注意事项
Refresh Token 必须HttpOnly + Secure(防止XSS盗取)
短期Token有效期别太长(建议2小时以内)
单点登录(SSO)场景要额外处理
四、实际项目踩坑记录
去年我做的一个后台系统,Token过期问题特别严重,用户经常填表到一半被踢出。
优化前:Token 2小时过期,直接跳登录页,用户投诉爆炸
优化后:
- Access Token 2小时过期
- Refresh Token 7天过期
- 提前5分钟自动续期
- 最终用户几乎感知不到Token刷新,体验大幅提升!
五、知识延展
前端怎么无感刷新token
当 Token 过期时,前端可以使用以下两种无感刷新 Token 的方案:
1. 使用刷新Token(Refresh Token)
在登录成功后,后端会返回两个Token,一个是Access Token,一个是Refresh Token。前端需要将这两个Token保存到本地存储中,例如localStorage或sessionStorage中,以便在需要时使用。
当需要访问API时,前端将从本地存储中获取Access Token,并将其放入请求头中发送到后端。如果Access Token过期了,后端会返回一个错误响应,并提示前端进行刷新Token的操作。
前端可以使用下面的代码实现刷新Token的操作:
function refreshToken() {
const refreshToken = localStorage.getItem('refreshToken');
// 发送请求到后端,获取新的Access Token
fetch('/api/refreshToken', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ refreshToken })
})
.then(response => response.json())
.then(data => {
// 将新的Access Token更新到本地存储中
localStorage.setItem('accessToken', data.accessToken);
})
.catch(error => {
console.error('刷新Token失败:', error);
});
}
当需要刷新Token时,前端可以调用refreshToken函数,该函数会向后端发送请求,获取新的Access Token,并将其更新到本地存储中。在使用API时,前端需要检查Access Token是否过期,如果过期了,则需要调用refreshToken函数来获取新的Access Token。
2. 使用续期接口
在登录成功后,后端会返回一个Access Token和一个过期时间。前端可以将Access Token和过期时间保存到本地存储中,以便在需要时使用。
前端需要定时检查Access Token是否过期,如果过期了,则需要向后端发送续期请求来更新Access Token的过期时间。下面是一个示例代码:
function renewToken() {
const accessToken = localStorage.getItem('accessToken');
const expireTime = localStorage.getItem('expireTime');
// 计算AccessToken的剩余有效时间
const remainTime = expireTime - Date.now();
// 如果AccessToken的剩余有效时间小于5分钟,则发送续期请求
if (remainTime < 5 * 60 * 1000) {
// 发送续期请求到后端,更新AccessToken的过期时间
fetch('/api/renewToken', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ accessToken })
})
.then(response => response.json())
.then(data => {
// 将新的过期时间更新到本地存储中
localStorage.setItem('expireTime', data.expireTime);
})
.catch(error => {
console.error('续期Token失败:', error);
});
}
}
// 定时检查AccessToken的过期时间
setInterval(renewToken, 60 * 1000);
上面的代码中,renewToken函数会检查Access Token的过期时间,如果剩余有效时间小于5分钟,则会向后端发送续期请求来更新AccessToken的过期时间。在使用API时,前端需要定时调用renewToken函数来检查Access Token的过期时间,并更新过期时间。
六、总结
Token过期处理得好,用户体验直接起飞!核心思路:
- 短期Token + 长期Refresh Token
- Axios拦截器自动换新Token
- 提前续期避免卡顿
- 安全存储Refresh Token
如果你的项目还在用“Token过期就跳登录”的粗暴方案,赶紧优化吧!
到此这篇关于Vue如何优雅处理Token过期并自动续期的文章就介绍到这了,更多相关Vue处理Token过期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
