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!

推薦閱讀: