網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
401狀態(tài)碼的含義和處理
401狀態(tài)碼的含義
axios向服務(wù)器端發(fā)送請(qǐng)求時(shí),有兩種情況會(huì)出現(xiàn)401狀態(tài)碼(unauthorized未授權(quán)):
1. 服務(wù)端要求傳遞token信息,而實(shí)際發(fā)送請(qǐng)求時(shí)沒(méi)有傳遞。
2. 發(fā)送請(qǐng)求時(shí)有傳遞token到達(dá)服務(wù)器端,但由于時(shí)間比較久,這個(gè)token在服務(wù)器中已經(jīng)過(guò)期了(服務(wù)器存儲(chǔ)token有效期時(shí)間為2個(gè)小時(shí))。
總之,服務(wù)器端有些api接口要求傳遞token,token失效或沒(méi)有傳遞,就會(huì)報(bào)401錯(cuò)誤。
401狀態(tài)碼的處理
1. 在axios請(qǐng)求攔截器中做token傳遞操作。
2. 可以這樣設(shè)置,在axios響應(yīng)攔截器中判斷請(qǐng)求狀態(tài)如果是401,就強(qiáng)制用戶重新登錄系統(tǒng)。
第2種情況處理實(shí)現(xiàn):
在axios的響應(yīng)攔截器中,判斷錯(cuò)誤碼等于401就強(qiáng)制登錄(utils/ax.js)
// 引入路由 import router from '@/router' // 配置響應(yīng)攔截器 axios.interceptors.response.use(function (response) { ? // 正常響應(yīng)處理 ? return response }, function (error) { ? // 非正常響應(yīng)處理(包括401) ? // console.dir(error) // 對(duì)象: config request response isAxiosError toJSON ? if (error.response.status === 401) { ? ? // token失效(token在服務(wù)器端已經(jīng)失效了,2個(gè)小時(shí)時(shí)效) ? ? // 強(qiáng)制用戶重新登錄系統(tǒng),以刷新服務(wù)器端的token時(shí)效 ? ? router.push('/login') ? ? // 不要給做錯(cuò)誤提示了 ? ? return new Promise(function () {}) // 空的Promise對(duì)象,沒(méi)有機(jī)會(huì)執(zhí)行catch,進(jìn)而不做錯(cuò)誤提示了 ? } ? // return new Promise((resolve,reject)=>{ ? // reject('獲得文章失??!') ? // }) ? return Promise.reject(error) })
注意:
1. 路由對(duì)象.push(xxx) 可以實(shí)現(xiàn)編程式導(dǎo)航。
2. 路由對(duì)象:在組件中是 this.$router ,在main.js/ax.js文件中就是router對(duì)象(需要import導(dǎo)入)。
模擬服務(wù)器端token失效步驟:
1. 刪除客戶端sessionStorage數(shù)據(jù)。
2. 暫時(shí)屏蔽守衛(wèi)代碼(開(kāi)發(fā)完畢再打開(kāi))。
401狀態(tài)碼升級(jí)處理
401狀態(tài)碼
axios向服務(wù)器端發(fā)送請(qǐng)求時(shí)有兩種情況會(huì)出現(xiàn)401狀態(tài)碼(unauthorized未授權(quán)):
1. 服務(wù)端要求傳遞token信息,而實(shí)際沒(méi)有傳遞。
2. 有傳遞token到達(dá)服務(wù)器端,但由于時(shí)間比較久,這個(gè)token在服務(wù)器中已經(jīng)過(guò)期了(服務(wù)器存儲(chǔ)token有效期時(shí)間為2個(gè)小時(shí))。
總之,服務(wù)器端有些api接口要求傳遞token,token失效或沒(méi)有傳遞,就會(huì)報(bào)401錯(cuò)誤。
相關(guān)處理
1. 第1種情況,可以在axios請(qǐng)求攔截器中做token傳遞操作。
2. 第2種情況,之前是這樣處理的,在axios響應(yīng)攔截器中判斷請(qǐng)求狀態(tài)如果是401,就強(qiáng)制用戶重新登錄系統(tǒng)
這樣處理用戶體驗(yàn)非常不好,現(xiàn)在做一次升級(jí)優(yōu)化處理。?
服務(wù)器端返回兩個(gè)秘鑰信息,它們?cè)诜?wù)端都有使用時(shí)效:
-
token
有效期2小時(shí)。 -
refresh_token
有效期14天,refresh_token用于在token過(guò)期后,重新獲取并刷新token時(shí)效使用的。
針對(duì)第2種401狀態(tài)碼處理步驟為:
1. 判斷refresh_token是否存在
不存在就直接重新登錄。
存在,axios發(fā)起請(qǐng)求,帶著refresh_token請(qǐng)求服務(wù)端,獲取新token出來(lái):
成功:對(duì)vuex和localStorage進(jìn)行token信息更新。
失敗:清空無(wú)效用戶信息,直接重新登錄。
示例代碼1?
// 響應(yīng)攔截器 (響應(yīng)成功:剝離無(wú)效數(shù)據(jù),響應(yīng)失?。核⑿聇oken) instance.interceptors.response.use(res => { // 將來(lái)獲取數(shù)據(jù):res.data.data 麻煩 // 想要結(jié)果:data 即可 try { return res.data.data } catch (e) { return res } }, async err => { try { // 目的:刷新token if (err.response && err.response.status === 401) { // 未登錄 跳轉(zhuǎn)登錄頁(yè)面 阻止程序運(yùn)行 const { user } = store.state // 如果沒(méi)有token沒(méi)登錄 如果沒(méi)有refresh_token無(wú)法刷新token if (!user.token || !user.refresh_token) { router.push('/login') return Promise.reject(err) } // 刷新token,發(fā)請(qǐng)求,沒(méi)有配置的axios,自己配置refresh_token const res = await axios({ url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations', method: 'put', headers: { Authorization: `Bearer ${user.refresh_token}` } }) // token獲取 res.data.data.token // 更新 vuex 和 本地 token store.commit('setUser', { token: res.data.data.token, refresh_token: user.refresh_token }) // 繼續(xù)發(fā)送剛才錯(cuò)誤的請(qǐng)求 // instance({之前錯(cuò)誤的請(qǐng)求配置}) // err錯(cuò)誤對(duì)象 包含(response 響應(yīng)對(duì)象 |config 請(qǐng)求配置) return instance(err.config) } } catch (e) { // exception 異常 // 刷新token失敗 router.push('/login') return Promise.reject(e) } return Promise.reject(err) })
演示代碼:promise錯(cuò)誤處理:
示例代碼2
import store from '@/store' // 引入vuex中的store實(shí)例 import router from '@/router' // 引入路由對(duì)象實(shí)例 …… // 響應(yīng)攔截器 instance.interceptors.response.use( function (response) { try { // 返回具體有價(jià)值的業(yè)務(wù)數(shù)據(jù) return response.data.data } catch (error) { return response.data } }, async function (error) { // 響應(yīng)有錯(cuò)誤,有可能錯(cuò)誤狀態(tài)碼為401 if (error.response && error.response.status === 401) { // 定義登錄路由對(duì)象 let toPath = { name: 'login', query: { redirectUrl: router.currentRoute.path } } // 跳轉(zhuǎn)對(duì)象 // 如果refresh_token不存在 if (!store.state.user.refresh_token) { router.push(toPath) return Promise.reject(error) } try { // 刷新用戶token // 應(yīng)該發(fā)送一個(gè)請(qǐng)求 換取新的token // 這里不應(yīng)該再用instance 因?yàn)?instance會(huì)再次進(jìn)入攔截器 用默認(rèn)的axios let result = await axios({ method: 'put', url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations', headers: { Authorization: `Bearer ${store.state.user.refresh_token}` } }) // 獲取到新token后,就對(duì)vuex和localStorage進(jìn)行更新 store.commit('updateUser', { token: result.data.data.token, // 拿到新的token之后 refresh_token: store.state.user.refresh_token // 將之前 refresh_token 14天有效期 }) return instance(error.config) // 把剛才錯(cuò)誤的請(qǐng)求再次發(fā)送出去 然后將promise返回 } catch (err) { // 如果錯(cuò)誤 表示補(bǔ)救措施也沒(méi)用了(有可能refresh_token也失效了) // 應(yīng)該跳轉(zhuǎn)到登錄頁(yè) 并且 把廢掉的用戶信息全都干掉 store.commit('clearUser') // 所有的用戶信息清空 router.push(toPath) // 跳轉(zhuǎn)到回登錄頁(yè) return Promise.reject(err) } } return Promise.reject(error) } ) ') // 所有的用戶信息清空 router.push(toPath) // 跳轉(zhuǎn)到回登錄頁(yè) return Promise.reject(err) } } return Promise.reject(error) } )
原文鏈接:https://blog.csdn.net/jyn15159/article/details/108879988
相關(guān)推薦
- 2022-09-17 利用Python提取PDF文本的簡(jiǎn)單方法實(shí)例_python
- 2022-09-18 K8s實(shí)戰(zhàn)教程之容器和?Pods資源分配問(wèn)題_云其它
- 2022-05-27 numpy模塊中axis的理解與使用_python
- 2022-07-07 Pandas提高數(shù)據(jù)分析效率的13個(gè)技巧匯總_python
- 2023-02-05 如何用C#獲取計(jì)算機(jī)詳細(xì)的軟件和硬件信息_C#教程
- 2022-09-24 基于Pytorch實(shí)現(xiàn)邏輯回歸_python
- 2022-12-25 一文帶你熟悉Go語(yǔ)言中的分支結(jié)構(gòu)_Golang
- 2023-02-17 golang基礎(chǔ)之waitgroup用法以及使用要點(diǎn)_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支