前端登錄token失效實(shí)現(xiàn)雙Token無感刷新詳細(xì)步驟
一、方案背景
在用戶登錄系統(tǒng)后,為了保障安全性和用戶體驗(yàn),通常采用Token
機(jī)制進(jìn)行身份驗(yàn)證。然而,單一的 Token
存在過期問題,導(dǎo)致用戶需要頻繁重新登錄,影響使用體驗(yàn)。為解決這一問題,本方案提出采用雙Token
機(jī)制實(shí)現(xiàn)前端登錄不掉線的無感刷新。
二、方案目標(biāo)
- 實(shí)現(xiàn)用戶登錄后,在
Token
過期前自動(dòng)刷新,避免用戶頻繁重新登錄。 - 確保刷新過程對用戶無感知,不影響用戶正常操作。
- 保障系統(tǒng)的安全性,防止非法訪問。
三、技術(shù)原理
3.1. 雙 Token 機(jī)制
Access Token
:用于用戶身份驗(yàn)證,設(shè)置較短的過期時(shí)間(如 30 分鐘)。在每次請求時(shí),前端將Access Token
添加到請求頭中,服務(wù)器驗(yàn)證其有效性后返回請求結(jié)果。Refresh Token
:用于獲取新的Access Token
,設(shè)置較長的過期時(shí)間(如 7 天)。當(dāng)Access Token
過期時(shí),前端使用Refresh Token
向服務(wù)器請求新的Access Token
。
3.2. 無感刷新流程
- 前端在發(fā)送請求時(shí),先檢查
Access Token
是否過期。如果未過期,正常發(fā)送請求。 - 如果
Access Token
過期,前端攔截該請求,并使用Refresh Token
發(fā)起刷新請求。 - 服務(wù)器驗(yàn)證
Refresh Token
的有效性,如果有效,返回新的Access Token
和Refresh Token
。 - 前端保存新的
Access Token
和Refresh Token
,并重新發(fā)送之前被攔截的請求。
四、具體實(shí)現(xiàn)步驟
4.1. 登錄流程
- 用戶輸入用戶名和密碼進(jìn)行登錄,前端將登錄信息發(fā)送給服務(wù)器。
- 服務(wù)器驗(yàn)證登錄信息成功后,生成
Access Token
和Refresh Token
,并將其返回給前端。 - 前端將
Access Token
和Refresh Token
保存到本地存儲(chǔ)(如LocalStorage
)中。
4.2. 請求攔截
- 使用前端框架的攔截器(如
Vue
的axios
攔截器)攔截所有請求。 - 在請求發(fā)送前,從本地存儲(chǔ)中獲取
Access Token
,并將其添加到請求頭中。
axios.interceptors.request.use((config) => { const access_token = localStorage.getItem("access_token"); if (access_token) { config.headers.Authorization = `Bearer ${access_token}`; } return config; });
4.3. 響應(yīng)攔截與刷新
- 攔截服務(wù)器返回的響應(yīng),檢查響應(yīng)狀態(tài)碼。如果狀態(tài)碼為
401
(表示Access Token
過期),則執(zhí)行刷新操作。 - 設(shè)置一個(gè)標(biāo)志位
isRefreshing
,防止多個(gè)請求同時(shí)觸發(fā)刷新流程。當(dāng)isRefreshing
為true
時(shí),后續(xù)請求將被暫存到一個(gè)隊(duì)列中,等待刷新完成后再重新發(fā)送。 - 使用
Refresh Token
發(fā)起刷新請求,請求新的Access Token
和Refresh Token
。 - 在刷新請求成功后,更新本地存儲(chǔ)中的
Access Token
和Refresh Token
,并將標(biāo)志位isRefreshing
設(shè)置為false
。 - 遍歷請求隊(duì)列,重新發(fā)送之前被攔截的請求。
axios.interceptors.response.use( (response) => { return response; }, async (error) => { const { data, status, config } = error.response; if (status === 401 && config.url !== "/refresh") { const isRefreshing = false; if (!isRefreshing) { isRefreshing = true; try { const res = await api.get("/refresh", { params: { token: localStorage.getItem("refresh_token"), }, }); localStorage.setItem("access_token", res.data.access_token); localStorage.setItem("refresh_token", res.data.refresh_token); isRefreshing = false; // 重新發(fā)送之前被攔截的請求 return api(config); } catch (err) { // 刷新失敗,跳轉(zhuǎn)到登錄頁面 window.location.href = "/login"; } } else { // 將請求添加到隊(duì)列中,等待刷新完成后再重新發(fā)送 requests.push(() => api(config)); } } return Promise.reject(error); } );
4.4. 錯(cuò)誤處理:
- 如果刷新請求失?。ㄈ?
Refresh Token
過期或無效),則跳轉(zhuǎn)到登錄頁面,提示用戶重新登錄。 - 對于其他類型的錯(cuò)誤,根據(jù)具體情況進(jìn)行相應(yīng)的處理,如顯示錯(cuò)誤信息等。
五、安全性考慮
- HTTPS 協(xié)議:確保所有通信都通過 HTTPS 協(xié)議進(jìn)行,防止
Token
在傳輸過程中被竊取。 - 設(shè)置合理的過期時(shí)間:根據(jù)系統(tǒng)的安全要求和用戶體驗(yàn),合理設(shè)置
Access Token
和Refresh Token
的過期時(shí)間。Access Token
過期時(shí)間較短,減少被濫用的風(fēng)險(xiǎn);Refresh Token
過期時(shí)間較長,但也要定期更換,增加安全性。 - 防止
Refresh Token
泄露:對Refresh Token
進(jìn)行嚴(yán)格的保護(hù),避免泄露。例如,不要在URL
中傳遞Refresh Token
,只在請求頭中傳遞。 - 限制刷新次數(shù):可以設(shè)置
Refresh Token
的刷新次數(shù)限制,防止被惡意刷新。
六、性能優(yōu)化
- 減少刷新頻率:通過合理設(shè)置
Access Token
的過期時(shí)間,盡量減少刷新操作的頻率。 - 緩存機(jī)制:對于一些不經(jīng)常變化的數(shù)據(jù),可以使用緩存機(jī)制,減少請求次數(shù),提高系統(tǒng)性能。
- 合并請求:在可能的情況下,將多個(gè)請求合并為一個(gè)請求,減少網(wǎng)絡(luò)請求的次數(shù)。
七、總結(jié)
本方案通過采用雙 Token
機(jī)制,實(shí)現(xiàn)了前端登錄不掉線的無感刷新。在保障系統(tǒng)安全性的前提下,提高了用戶體驗(yàn),減少了用戶頻繁重新登錄的麻煩。同時(shí),通過合理的安全性考慮和性能優(yōu)化措施,確保系統(tǒng)的穩(wěn)定性和高效性。在實(shí)際應(yīng)用中,可以根據(jù)具體業(yè)務(wù)需求進(jìn)行適當(dāng)?shù)恼{(diào)整和優(yōu)化。
到此這篇關(guān)于前端登錄token失效實(shí)現(xiàn)雙Token無感刷新的文章就介紹到這了,更多相關(guān)前端雙Token無感刷新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Javascript 完美運(yùn)動(dòng)框架(逐行分析代碼,讓你輕松了運(yùn)動(dòng)的原理)
這篇文章主要介紹了Javascript 完美運(yùn)動(dòng)框架,逐行分析代碼,讓你輕松了運(yùn)動(dòng)的原理,需要的朋友可以參考下2015-01-01chrome瀏覽器不支持onmouseleave事件的解決技巧
發(fā)現(xiàn)給div加的 onmouseleave事件在chrome 中不起效果,下面與大家分享下具體的解決方法,不會(huì)的朋友可以了解下哈,希望對大家有所幫助2013-05-05原生JS實(shí)現(xiàn)Ajax跨域請求flask響應(yīng)內(nèi)容
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)Ajax跨域請求flask響應(yīng)內(nèi)容,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10javascript實(shí)現(xiàn)點(diǎn)擊按鈕切換圖片
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)點(diǎn)擊按鈕切換圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08記一次webpack3升級(jí)webpack4的踩坑經(jīng)歷
這篇文章主要介紹了記一次webpack3升級(jí)webpack4的踩坑經(jīng)歷,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06全面了解addEventListener和on的區(qū)別
下面小編就為大家?guī)硪黄媪私鈇ddEventListener和on的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07JS數(shù)據(jù)雙向綁定原理與用法實(shí)例分析
這篇文章主要介紹了JS數(shù)據(jù)雙向綁定原理與用法,結(jié)合實(shí)例形式分析了JavaScript數(shù)據(jù)雙向綁定相關(guān)原理、實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2019-11-11