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

Vue SPA中Axios拦截器Token更新后请求复用旧Token问题排查

Hey, let's figure out why your updated token isn't being picked up by subsequent requests and fix it step by step.

First, the core issue here is: your request interceptor reads the token from localStorage at the moment the request is initiated. When you update localStorage in the response interceptor, any pending requests have already passed the request interception stage and are still carrying the old token. Plus, your 401 retry logic has potential race conditions that prevent it from grabbing the latest token reliably.

We can fix this by maintaining a global token variable, which ensures all requests get the most up-to-date token in real time instead of relying on the timing of localStorage reads.

Here's the adjusted complete code:

// Initialize global token variable with the value from localStorage
let currentToken = window.localStorage.getItem('authToken');

// Request interceptor: Use the global token to set the request header
axios.interceptors.request.use(config => {
  if (currentToken) {
    config.headers.Authorization = `Bearer ${currentToken}`;
  }
  return Promise.resolve(config);
});

// Response interceptor: Handle new token returns and 401 retries
axios.interceptors.response.use(
  response => {
    // Check if the response carries a new token
    if (response.data.meta?.tokens?.Bearer) {
      const newToken = response.data.meta.tokens.Bearer;
      console.log('Setting new token:', newToken);
      // Update both the global variable and localStorage to keep them in sync
      currentToken = newToken;
      window.localStorage.setItem('authToken', newToken);
    }
    return response;
  },
  error => {
    const originalRequest = error.config;
    // Only handle 401 errors that haven't been retried yet to avoid infinite loops
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      // Sync the global token with localStorage as a safeguard against inconsistencies
      currentToken = window.localStorage.getItem('authToken');
      
      if (currentToken) {
        // Update the original request's Authorization header with the latest token
        originalRequest.headers.Authorization = `Bearer ${currentToken}`;
        // Resend the request
        return axios(originalRequest);
      } else {
        // If no valid token exists, redirect to login or handle authentication logic here
        // Example: router.push('/login');
        return Promise.reject(error);
      }
    }
    return Promise.reject(error);
  }
);

Why this works:

  • Global token variable: The request interceptor uses this variable directly instead of reading from localStorage every time. When the response interceptor updates this variable, all subsequent requests (including retries) immediately use the latest token, eliminating lag.
  • Synchronized updates: When a new token is received, we update both the global variable and localStorage to ensure data consistency—this keeps the token persisted while maintaining real-time availability.
  • Optimized retry logic: Before retrying, we sync the global token with localStorage to guarantee we're using the latest value, then update the original request's header to avoid failing again with the old token.

If you ever run into scenarios where multiple requests trigger 401 at the same time (like when a token expires mid-concurrent requests), you could add a lock mechanism to avoid redundant retries. But based on your description of the server returning tokens in responses, this might not be necessary right now.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:25:57