vue中Axios加上回调函数更新token的实现方式

lxf2023-03-16 07:28:01

不断写作,加速成长!这个是我参加「AdminJS日新的目标 · 10 月更文考验」第32天,查看更多活动规则

vue中Axios加上回调函数更新token的实现方式

Axios是一款互联网前面要求架构,文中主要介绍了vue中Axios加上回调函数更新token的实现方式,

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,然后重新要求的形式。