Vue?Token過期問題的2種解決方案小結(jié)
對(duì)于token過期,我們有兩種方案:
方案一:當(dāng)我們操作某個(gè)需要token作為請(qǐng)求頭的接口時(shí),返回的數(shù)據(jù)錯(cuò)誤error.response.status === 401,說明我們的token已經(jīng)過期了。
我們希望當(dāng)響應(yīng)返回的數(shù)據(jù)是401身份過期時(shí),讓當(dāng)前瀏覽頁面強(qiáng)行跳轉(zhuǎn)到登入頁面,讓用戶手動(dòng)更新token。拿到最新的token值后再跳回之前瀏覽的頁面。增強(qiáng)用戶體驗(yàn)。
實(shí)現(xiàn)原理:
再阻攔響應(yīng)器中配置:
// 阻攔響應(yīng)器 request.interceptors.response.use(function (response) { return response }, async function (error) { if (error.response && error.response.status === 401) { // token續(xù)簽方式1: //清空當(dāng)前vuex保存的token(我們這的vuex和本地已經(jīng)建立了關(guān)系,相當(dāng)于也清空了本地token) store.commit('upUser', '') console.log(router.currentRoute.fullPath)// 當(dāng)前路由的完整路徑(#后面的) //這里我們采用?path=的方式保存當(dāng)前瀏覽頁面的完整路徑, // push()會(huì)產(chǎn)生歷史記錄 而replace不會(huì)有歷史記錄 router.push({ path: `/login?path=${router.currentRoute.fullPath}` }) } return Promise.reject(error) })
再登入組件中給登入功能函數(shù)添加:
this.$router.replace({
path: this.$route.query.path || '/'
})
// 1.點(diǎn)擊登入 async onSubmit () { try { const { data: res } = await loginAPI(this.user) //登錄成功 // 不嚴(yán)謹(jǐn)?shù)姆祷厣洗螢g覽的頁面 // this.$router.back() // 推薦方式: // 登錄后, 判斷有未遂地址(有未遂地址的情況是:token過期,在阻攔響應(yīng)器中實(shí)現(xiàn)對(duì)未遂地址的保存), 登入成功后跳轉(zhuǎn)到未遂地址, 否則去/路徑(跳到首頁--這種情況是:用戶主動(dòng)前往登入頁面的登入,沒有未遂地址,登入成功后直接前往首頁) // replace不會(huì)產(chǎn)生路由歷史記錄 this.$router.replace({ path: this.$route.query.path || '/' }) // 存儲(chǔ)獲取過來的token this.$store.commit('upUser', res.data) } catch (err) { console.log(err) if (err.response.status === 400) { this.$toast.fail('手機(jī)號(hào)或驗(yàn)證碼錯(cuò)誤') } else { this.$toast.fail('登入失敗,請(qǐng)稍后再試') // 可能由于網(wǎng)絡(luò)問題導(dǎo)致的登入失敗 } } },
方案二:實(shí)現(xiàn)用戶無感知的刷新token值,我們希望當(dāng)響應(yīng)返回的數(shù)據(jù)是401身份過期時(shí),響應(yīng)阻攔器自動(dòng)幫我們刷新token值,而不是讓用戶手動(dòng)更新token。拿到最新的token值后再重新發(fā)起剛剛因token過期的請(qǐng)求。從而實(shí)現(xiàn)無感知
前提是有后臺(tái)的配合:
登入后后臺(tái)接口返回值要求:必須提供刷新token的令牌
并且后臺(tái)提供了刷新token的接口: (請(qǐng)求頭要求是refresh_token)
注意:1. 在請(qǐng)求響應(yīng)器中做判斷在非刷新token的時(shí)候,給請(qǐng)求頭配置token,而刷新token的時(shí)候,我們自己手動(dòng)添加請(qǐng)求頭為refresh_token
2.refresh_token也有過期的時(shí)候,這時(shí)只能強(qiáng)行讓用戶自己重新登入了
// 刷新用戶token export const updataTokenAPI = function () { return request({ method: 'PUT', url: '/v1_0/authorizations', headers: { Authorization: `Bearer ${store.state.user.refresh_token}` } }) }
實(shí)現(xiàn)原理:
import request from '@/utils/request' import store from '@/store' // 請(qǐng)求響應(yīng)器 request.interceptors.request.use(function (config) { // config :本次請(qǐng)求的配置對(duì)象 // config 里面有一個(gè)屬性:headers const { user } = store.state //請(qǐng)求頭未配置信息的時(shí)候才會(huì)配置 if (user.token && config.headers.Authorizatio === undefined) { config.headers.Authorization = `Bearer ${user.token}` } // 這里必須將config返回出去,否則請(qǐng)求會(huì)停在這 里 return config }, function (error) { // 如果請(qǐng)求出錯(cuò)(還沒發(fā)送出去,可能是代碼寫錯(cuò)了的問題),就會(huì)進(jìn)入這里 return Promise.reject(error) }) // 阻攔響應(yīng)器 request.interceptors.response.use(function (response) { return response }, async function (error) { if (error.response && error.response.status === 401) { // token續(xù)簽方式2: refreshToken(用戶無感知) // 將過期的token值清空 store.commit('updataToken', '') //請(qǐng)求刷新token接口 const { data: res } = await updataTokenAPI() //保存新的token值 store.commit('updataToken', res.data.token) // 再調(diào)用一次未完成的請(qǐng)求啊(用戶無感知) // error.config 就是上一次axios請(qǐng)求的配置對(duì)象 // console.dir(error.config) // 把新的token賦予到下一次axios請(qǐng)求的請(qǐng)求頭中 error.config.headers.Authorization = 'Bearer ' + res.data.token // return到await的地方,將未完成的請(qǐng)求再次發(fā)起, return axios(error.config) } else if (error.response.status === 500 && error.config.url === '/v1_0/authorizations') { // 因?yàn)?00的情況有很多種,refresh_token失效也是其中一種情況,所有再加上error.config.url === '/v1_0/authorizations'條件,確保是refresh_token失效情況 // 清空所有的token和refresh_toekn,并且強(qiáng)制跳轉(zhuǎn)登錄頁面 store.commit('upUser', {}) router.push({ path: '/login' }) Toast.fail('身份已過期') } return Promise.reject(error) })
總結(jié)
到此這篇關(guān)于Vue Token過期問題的2種解決方案的文章就介紹到這了,更多相關(guān)Vue Token過期問題解決內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)現(xiàn)大屏頁面的屏幕自適應(yīng)
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)大屏頁面的屏幕自適應(yīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10Vue3使用MD5加密實(shí)戰(zhàn)案例(清晰明了)
MD5是一種信息摘要算法(對(duì)稱加密),一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個(gè)128位(16字節(jié))的散列值,用來確保信息傳輸完整一致性,這篇文章主要給大家介紹了關(guān)于Vue3使用MD5加密的相關(guān)資料,需要的朋友可以參考下2023-05-05Vue項(xiàng)目中使用jsonp抓取跨域數(shù)據(jù)的方法
這篇文章主要介紹了Vue項(xiàng)目中使用jsonp抓取跨域數(shù)據(jù)的方法,本文通過實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2019-11-11vue實(shí)踐---根據(jù)不同環(huán)境,自動(dòng)轉(zhuǎn)換請(qǐng)求的url地址操作
這篇文章主要介紹了vue實(shí)踐---根據(jù)不同環(huán)境,自動(dòng)轉(zhuǎn)換請(qǐng)求的url地址操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09vue報(bào)錯(cuò)之exports is not defined問題的解決
這篇文章主要介紹了vue報(bào)錯(cuò)之exports is not defined問題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07詳細(xì)講解如何創(chuàng)建, 發(fā)布自己的 Vue UI 組件庫
當(dāng)我們自己開發(fā)了一個(gè) _UI Component_, 需要在多個(gè)項(xiàng)目中使用的時(shí)候呢? 我們首先想到的可能是直接復(fù)制一份過去對(duì)嗎?我們?yōu)槭裁床话l(fā)布一個(gè) UI 組件庫給自己用呢?下面小編和大家來一起學(xué)習(xí)下吧2019-05-05Vue項(xiàng)目之學(xué)生管理系統(tǒng)實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了Vue項(xiàng)目之學(xué)生管理系統(tǒng)實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03