You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用Token至过期后再重新获取?(JS/TS实现)

解决Axios拦截器重复获取Token导致429错误的方案

问题现状

当前axios请求拦截器中,每次发起请求都会调用LoginAPI.API.Signin.run()获取Token,导致短时间内大量请求触发429(请求过于频繁)错误。需要实现Token复用机制:仅在Token不存在或已过期时,才重新请求新Token,避免重复调用登录接口。

代码改造步骤

1. 扩展LoginAPI,增加Token过期时间管理

修改Login.e2e.ts,新增Token过期时间状态,并在登录成功后计算过期时间(假设登录接口返回的res.data包含expires_in字段,单位为秒):

import api from "api/core"
import { expect } from "@playwright/test";

export const LoginAPI = {
  States: {
    token: "" as string,
    expiresAt: 0 as number // 存储Token过期时间戳(毫秒)
  },

  API: {
    Signin: {
      notes: "user login",
      run: async () => {
        const res: any = await api.test.LoginPost(process.env.NAME, process.env.PASS)
        LoginAPI.States.token = res.data.token
        // 计算过期时间:当前时间 + expires_in秒(转毫秒)
        LoginAPI.States.expiresAt = Date.now() + (res.data.expires_in * 1000)
        expect(res.status).toBe(200)
      },
    },
  },

  // 判断Token是否有效(存在且未过期)
  isTokenValid(): boolean {
    return !!LoginAPI.States.token && Date.now() < LoginAPI.States.expiresAt
  }
};

2. 改造Axios拦截器,实现Token复用与并发控制

修改axios.ts,添加并发请求锁(避免多个请求同时触发登录),仅在Token无效时才调用登录接口:

import axios from "axios";
import { LoginAPI } from "../playwright/tests/login/login.api";

const customAxios = axios.create({
    baseURL: process.env.ENV === '1' ? "https://test1" : process.env.ENV === '2' ? "https://test2" : "https://test3",
});

// 全局登录Promise,用于并发请求时避免重复登录
let loginPromise: Promise<void> | null = null;

customAxios.interceptors.request.use(
    async (config) => {
        // 1. 检查Token是否有效
        if (!LoginAPI.isTokenValid()) {
            // 2. 若已有登录请求在进行,直接复用该Promise
            if (!loginPromise) {
                loginPromise = LoginAPI.API.Signin.run().finally(() => {
                    // 登录完成后清空Promise锁
                    loginPromise = null;
                });
            }
            await loginPromise;
        }

        // 3. 给请求头添加Token
        if (config.headers) {
            config.headers['Authorization'] = `Bearer ${LoginAPI.States.token}`;
        }
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

export default customAxios

关键逻辑说明

  • Token有效性判断:通过isTokenValid()方法检查Token是否存在且未到过期时间,避免无效Token被使用。
  • 并发请求控制:使用loginPromise锁,当多个请求同时发现Token过期时,只会发起一次登录请求,其余请求等待该Promise完成后复用新Token,彻底避免重复登录导致的429错误。
  • 过期时间计算:基于登录接口返回的expires_in计算过期时间戳,确保Token在有效期内被复用,过期后自动触发重新登录。

内容的提问来源于stack exchange,提问作者YusufOzt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:01:17