Vue如何優(yōu)雅處理Token過期并自動續(xù)期
大家好,干了6年前端,和Token斗智斗勇了不知道多少回。最煩的就是用戶正填著表單呢,突然跳登錄頁——Token過期了!今天就跟大家聊聊如何優(yōu)雅處理Token過期,甚至讓它自動續(xù)期,讓用戶無感知!
一、Token過期,用戶的噩夢
想象一下:
- 用戶填了半小時的報銷單,點擊提交—— “登錄失效,請重新登錄”
- 購物車選了半天,結算時——跳轉登錄頁
血壓直接拉滿,用戶體驗直接崩盤!
常見處理方式(但不夠優(yōu)雅)
- 粗暴型:Token過期直接跳登錄頁(用戶罵娘)
- 提醒型:彈窗提示“登錄已過期”(用戶還是得手動操作)
- 輪詢檢查型:定時檢查Token是否快過期(浪費請求)
但今天我要講的是更高級的玩法——無感知自動續(xù)期!
二、Token自動續(xù)期方案
1. 方案核心思路
- 短期Token(Access Token) :用來做日常請求(比如2小時過期)
- 長期Token(Refresh Token) :用來換新Token(比如7天過期)
流程:
- 用戶登錄,拿到
access_token和refresh_token access_token過期后,用refresh_token去換新的- 如果
refresh_token也過期了,才讓用戶重新登錄
2. 前端如何實現(xiàn)
(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)
// 重新發(fā)之前的請求
originalRequest.headers.Authorization = `Bearer ${access_token}`
return axios(originalRequest)
} catch (refreshError) {
// refresh_token 也過期了,跳登錄頁
window.location.href = '/login'
}
}
return Promise.reject(error)
}
)
(2)提前續(xù)期(更絲滑)
如果等Token完全過期再換新,用戶可能會遇到卡頓。更優(yōu)解是在Token快過期時提前續(xù)期:
// 檢查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分鐘過期,就續(xù)期
if (expiresIn < 5 * 60 * 1000) {
refreshToken()
}
}
// 定時檢查(每10分鐘一次)
setInterval(checkTokenExpiry, 10 * 60 * 1000)
三、安全注意事項
Refresh Token 必須HttpOnly + Secure(防止XSS盜?。?/p>
短期Token有效期別太長(建議2小時以內(nèi))
單點登錄(SSO)場景要額外處理
四、實際項目踩坑記錄
去年我做的一個后臺系統(tǒng),Token過期問題特別嚴重,用戶經(jīng)常填表到一半被踢出。
優(yōu)化前:Token 2小時過期,直接跳登錄頁,用戶投訴爆炸
優(yōu)化后:
- Access Token 2小時過期
- Refresh Token 7天過期
- 提前5分鐘自動續(xù)期
- 最終用戶幾乎感知不到Token刷新,體驗大幅提升!
五、知識延展
前端怎么無感刷新token
當 Token 過期時,前端可以使用以下兩種無感刷新 Token 的方案:
1. 使用刷新Token(Refresh Token)
在登錄成功后,后端會返回兩個Token,一個是Access Token,一個是Refresh Token。前端需要將這兩個Token保存到本地存儲中,例如localStorage或sessionStorage中,以便在需要時使用。
當需要訪問API時,前端將從本地存儲中獲取Access Token,并將其放入請求頭中發(fā)送到后端。如果Access Token過期了,后端會返回一個錯誤響應,并提示前端進行刷新Token的操作。
前端可以使用下面的代碼實現(xiàn)刷新Token的操作:
function refreshToken() {
const refreshToken = localStorage.getItem('refreshToken');
// 發(fā)送請求到后端,獲取新的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時,前端可以調(diào)用refreshToken函數(shù),該函數(shù)會向后端發(fā)送請求,獲取新的Access Token,并將其更新到本地存儲中。在使用API時,前端需要檢查Access Token是否過期,如果過期了,則需要調(diào)用refreshToken函數(shù)來獲取新的Access Token。
2. 使用續(xù)期接口
在登錄成功后,后端會返回一個Access Token和一個過期時間。前端可以將Access Token和過期時間保存到本地存儲中,以便在需要時使用。
前端需要定時檢查Access Token是否過期,如果過期了,則需要向后端發(fā)送續(xù)期請求來更新Access Token的過期時間。下面是一個示例代碼:
function renewToken() {
const accessToken = localStorage.getItem('accessToken');
const expireTime = localStorage.getItem('expireTime');
// 計算AccessToken的剩余有效時間
const remainTime = expireTime - Date.now();
// 如果AccessToken的剩余有效時間小于5分鐘,則發(fā)送續(xù)期請求
if (remainTime < 5 * 60 * 1000) {
// 發(fā)送續(xù)期請求到后端,更新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('續(xù)期Token失敗:', error);
});
}
}
// 定時檢查AccessToken的過期時間
setInterval(renewToken, 60 * 1000);
上面的代碼中,renewToken函數(shù)會檢查Access Token的過期時間,如果剩余有效時間小于5分鐘,則會向后端發(fā)送續(xù)期請求來更新AccessToken的過期時間。在使用API時,前端需要定時調(diào)用renewToken函數(shù)來檢查Access Token的過期時間,并更新過期時間。
六、總結
Token過期處理得好,用戶體驗直接起飛!核心思路:
- 短期Token + 長期Refresh Token
- Axios攔截器自動換新Token
- 提前續(xù)期避免卡頓
- 安全存儲Refresh Token
如果你的項目還在用“Token過期就跳登錄”的粗暴方案,趕緊優(yōu)化吧!
?到此這篇關于Vue如何優(yōu)雅處理Token過期并自動續(xù)期的文章就介紹到這了,更多相關Vue處理Token過期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue實現(xiàn)后臺管理權限系統(tǒng)及頂欄三級菜單顯示功能
這篇文章主要介紹了vue實現(xiàn)后臺管理權限系統(tǒng)及頂欄三級菜單顯示功能,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06
Vue 實時監(jiān)聽窗口變化 windowresize的兩種方法
這篇文章主要介紹了Vue 實時監(jiān)聽窗口變化 windowresize的兩種方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11

