vue中Axios添加攔截器刷新token的實現方法
Axios是一款網絡前端請求框架,基本用法如下:
1. Axios基本用法:
const response = await Axios.create({ baseURL: "https://test.api.com", headers: { 'Content-Type': 'application/json', }, }).post<RequestResponse>('/signin', { user_id: "test_user", password: "xxx", });
其中,RequestResponse是返回的數據要解析為的數據類型,如下:
export interface RequestResponse { data: any; message: string; resultCode: number; }
這樣,得到的response就是網絡請求的結果,可以進行判斷處理。
2. Axios基本封裝用法:
對Axios進行簡單的封裝,使得多個網絡請求可以使用統一的header等配置。
新建一個工具類,進行封裝:
import Axios, { AxiosRequestConfig, AxiosError, AxiosInstance, AxiosResponse } from 'axios'; export const BASE_URL = "https://test.api.com"; export const axiosApi = (): AxiosInstance => { const instance = Axios.create({ baseURL: BASE_URL, headers: { 'Content-Type': 'application/json', Authorization: `${getAccessToken()}`, }, }); return instance; } const getAccessToken = () => { // 這裡獲取本地保存的token return xxxxx }
然後使用的地方是這樣:
const response = await axiosApi().post<RequestResponse>('/signin', { user_id: "test_user", password: "xxx", });
3. 添加攔截器的用法
現在我們想再增加個功能,就是調接口時,header裡傳瞭token,但是有時候token過期瞭接口就會返回失敗,我們想在封裝的地方添加統一處理,如果token過期就刷新token,然後再調接口。
其中token的數據格式及解析方法已知如下:
import * as crypto from 'crypto'; import * as jwt from "jsonwebtoken"; export interface TokenData { userid: string; exp: number; iat: number; } export const decodeJWT = function (token: string): TokenData { if (!token) { return null; } const decoded = jwt.decode(token, { complete: true }); return decoded?.payload; };
如何統一刷新token呢?可以添加攔截器進行處理。把對Axios的封裝再改下,添加攔截器:
export const axiosApi = (): AxiosInstance => { const instance = Axios.create({ baseURL: BASE_URL, headers: { 'Content-Type': 'application/json', Authorization: `${getAccessToken()}`, }, }); // 添加攔截器 instance.interceptors.request.use( config => { return refreshToken(config); }, err => { return Promise.reject(err) } ) return instance; } // 刷新token的方法 const refreshToken = async (config: AxiosRequestConfig) => { const oldToken = getAccessToken(); if (!oldToken) { //如果本地沒有token,也就是沒登錄,那就不用刷新token return config; } const tokenData = decodeJWT(oldToken);//解析token,得到token裡包含的過期時間信息 const currentTimeSeconds = new Date().getTime()/1000; if (tokenData && tokenData.exp > currentTimeSeconds) { return config; // token數據裡的時間比當前時間大,也就是沒到過期時間,那也不用刷新 } // 下面是刷新token的邏輯,這裡是調API獲取新的token const response = await signInRefreshToken(tokenData?.userid); if (response && response.status == 200) { const { token, refresh_token } = response.data?.data; // 保存刷新後的token storeAccessToken(token); // 給API的header設置新的token config.headers.Authorization = token; } return config; }
經過這樣添加瞭攔截器,如果token沒過期,就直接進行網絡請求;如果token過期瞭,那就會調接口刷新token,然後給header設置新的token再進行網絡請求。
4. 註意事項:
要註意的一點是,實際應用時,要註意:
1.刷新token時如果調接口,所使用的網絡請求工具不能也使用這個封裝的工具,否則就會陷入無限循環,可以使用簡單未封裝的方式請求。
2.本例使用的方法,是進行請求前刷新token。也可以使用先調網絡請求,如果接口返回錯誤碼表示token過期,則刷新token,再重新請求的方式。
到此這篇關於vue中Axios添加攔截器刷新token的實現方法的文章就介紹到這瞭,更多相關Axios添加攔截器刷新token內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- TypeScript利用TS封裝Axios實戰
- vue3+vite+axios 配置連接後端調用接口的實現方法
- 在項目中封裝axios的實戰過程
- 十分鐘封裝一個好用的axios步驟示例
- Vue3+Vite使用雙token實現無感刷新