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