功能背景:后端技術(shù)調(diào)整后token過期非常短,短到10分鐘就過期了,所以在登錄之后會(huì)給前端一個(gè)refreshToken字段同AccessToken一并傳過來。token失效后利用refreshToken去延長用戶的登錄信息
1.功能難點(diǎn)
一個(gè)頁面請(qǐng)求一個(gè)接口報(bào)401權(quán)限錯(cuò)誤后,需要調(diào)用一個(gè)刷新AccessToken的接口,傳入refreshToken更新token信息。同時(shí),在請(qǐng)求到token之后,繼續(xù)請(qǐng)求上一步出錯(cuò)的接口。用戶并不會(huì)知道自己的登錄信息已經(jīng)過期了。
2.解決辦法
- 在vue項(xiàng)目中,我們采用 axios 來請(qǐng)求接口,一般我們都會(huì)對(duì)axios進(jìn)行一次封裝 $http,然后可以選擇把封裝好的 axios 綁定在vue原型上,這樣我們就可以在組件中用this.$http來請(qǐng)求接口了。
- this.$http請(qǐng)求返回的是一個(gè)promise,在請(qǐng)求之前axios有自己的攔截器(interceptors),對(duì)請(qǐng)求進(jìn)行攔截處理,一般的我們判斷接口401的時(shí)候,會(huì)跳轉(zhuǎn)到登錄頁,就可以在攔截器中統(tǒng)一做處理 。
- 上一步確定了在攔截器里面可以做處理。所以我們只需要在接口請(qǐng)求出錯(cuò),并且狀態(tài)status是401的時(shí)候,在攔截器的response,error回調(diào)函數(shù)去請(qǐng)求refreshToken接口,等到refreshToken接口返回了token之后,再return 請(qǐng)求上一步請(qǐng)求的接口繼續(xù)請(qǐng)求,否則return reject。
3.例子
axios.interceptors.response.use(success, async (error) => {
let {status} = error.response;
if (status == 401) {
let res = await getrefreshToken(refreshToken);
window.localstorage.token = res.token;
return axios.request(error.config);
}
return Promise.reject()
})
4.總結(jié)
一開始不太明白怎么在接口401之后請(qǐng)求完refreshToken之后,再去請(qǐng)求上一個(gè)出錯(cuò)的接口。后來一想,axios返回的是一個(gè)promise,只要狀態(tài)沒改變,那么then就不會(huì)執(zhí)行,一直在pending中,所以,在攔截器中error回調(diào)函數(shù)中去做處理,等請(qǐng)求到token之后在,重新請(qǐng)求一遍上一次報(bào)錯(cuò)的接口,再return 這個(gè)promise,那么在其他頁面的地方就不需要做什么處理,promise的狀態(tài)改變后,就直接會(huì)進(jìn)then或者catch方法里了。