溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

vue中Axios如何添加攔截器刷新token

發(fā)布時(shí)間:2022-02-15 13:38:05 來(lái)源:億速云 閱讀:243 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)vue中Axios如何添加攔截器刷新token,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

Axios是一款網(wǎng)絡(luò)前端請(qǐng)求框架,基本用法如下:

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是返回的數(shù)據(jù)要解析為的數(shù)據(jù)類型,如下:

export interface RequestResponse {
    data: any;
    message: string;
    resultCode: number;
}

這樣,得到的response就是網(wǎng)絡(luò)請(qǐng)求的結(jié)果,可以進(jìn)行判斷處理。

2. Axios基本封裝用法:

對(duì)Axios進(jìn)行簡(jiǎn)單的封裝,使得多個(gè)網(wǎng)絡(luò)請(qǐng)求可以使用統(tǒng)一的header等配置。

新建一個(gè)工具類,進(jìn)行封裝:

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. 添加攔截器的用法

現(xiàn)在我們想再增加個(gè)功能,就是調(diào)接口時(shí),header里傳了token,但是有時(shí)候token過(guò)期了接口就會(huì)返回失敗,我們想在封裝的地方添加統(tǒng)一處理,如果token過(guò)期就刷新token,然后再調(diào)接口。

其中token的數(shù)據(jù)格式及解析方法已知如下:

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;
};

如何統(tǒng)一刷新token呢?可以添加攔截器進(jìn)行處理。把對(duì)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) { //如果本地沒(méi)有token,也就是沒(méi)登錄,那就不用刷新token
    return config;
  }
 
  const tokenData = decodeJWT(oldToken);//解析token,得到token里包含的過(guò)期時(shí)間信息
  const currentTimeSeconds = new Date().getTime()/1000;
 
  if (tokenData && tokenData.exp > currentTimeSeconds) {
    return config; // token數(shù)據(jù)里的時(shí)間比當(dāng)前時(shí)間大,也就是沒(méi)到過(guò)期時(shí)間,那也不用刷新
  }
 
  // 下面是刷新token的邏輯,這里是調(diào)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設(shè)置新的token
    config.headers.Authorization = token;
  }
  return config;
}

經(jīng)過(guò)這樣添加了攔截器,如果token沒(méi)過(guò)期,就直接進(jìn)行網(wǎng)絡(luò)請(qǐng)求;如果token過(guò)期了,那就會(huì)調(diào)接口刷新token,然后給header設(shè)置新的token再進(jìn)行網(wǎng)絡(luò)請(qǐng)求。

4. 注意事項(xiàng):

要注意的一點(diǎn)是,實(shí)際應(yīng)用時(shí),要注意:

1.刷新token時(shí)如果調(diào)接口,所使用的網(wǎng)絡(luò)請(qǐng)求工具不能也使用這個(gè)封裝的工具,否則就會(huì)陷入無(wú)限循環(huán),可以使用簡(jiǎn)單未封裝的方式請(qǐng)求。

2.本例使用的方法,是進(jìn)行請(qǐng)求前刷新token。也可以使用先調(diào)網(wǎng)絡(luò)請(qǐng)求,如果接口返回錯(cuò)誤碼表示token過(guò)期,則刷新token,再重新請(qǐng)求的方式。

關(guān)于“vue中Axios如何添加攔截器刷新token”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI