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

React中AD认证IdToken过期后,如何实现刷新(静默/页面重载)?

IdToken过期自动刷新解决方案(基于MSAL.js)

一、静默刷新IdToken(推荐方案)

MSAL.js的acquireTokenSilent方法会自动检测缓存令牌的有效性,若令牌即将过期或已过期,将自动向AD发起静默请求刷新令牌。我们可以通过初始化检查、API请求拦截两种方式触发该逻辑。

1. 新增令牌刷新工具函数

修改app.tsx,添加以下函数:

import { InteractionRequiredAuthError } from '@azure/msal-browser';

// 静默获取/刷新IdToken
const refreshIdToken = async (msalInstance: PublicClientApplication) => {
  const activeAccount = msalInstance.getActiveAccount();
  if (!activeAccount) {
    msalInstance.loginRedirect();
    return;
  }

  try {
    const response = await msalInstance.acquireTokenSilent({
      account: activeAccount,
      scopes: [], // 与loginRequest保持一致
    });
    // 更新localStorage中的IdToken
    localStorage.setItem('authStatus', response.idToken);
    return response.idToken;
  } catch (error) {
    // 静默刷新失败(如用户长时间未操作需交互)
    if (error instanceof InteractionRequiredAuthError) {
      msalInstance.loginRedirect();
    } else {
      console.error('令牌刷新失败:', error);
    }
  }
};

2. 初始化时触发刷新

修改app.tsx中的账户初始化逻辑:

const accounts = msalInstance.getAllAccounts();

if (accounts.length > 0) {
  msalInstance.setActiveAccount(accounts[0]);
  // 页面加载时检查并刷新令牌
  refreshIdToken(msalInstance);
}

3. API请求前强制刷新

以Axios为例,添加请求拦截器确保每次API调用携带有效令牌:

import axios from 'axios';

const apiClient = axios.create({ baseURL: '/api' });

apiClient.interceptors.request.use(async (config) => {
  const idToken = await refreshIdToken(msalInstance);
  if (idToken) {
    config.headers.Authorization = `Bearer ${idToken}`;
  }
  return config;
}, (error) => Promise.reject(error));

二、页面重载时触发刷新

页面刷新时,检查本地存储的IdToken是否过期,若过期则触发静默刷新:

1. 新增过期检查函数

在app.tsx中添加:

// 解析IdToken并判断是否过期
const isIdTokenExpired = (idToken: string): boolean => {
  if (!idToken) return true;
  const payload = JSON.parse(atob(idToken.split('.')[1]));
  const expirationTime = payload.exp * 1000; // 转换为毫秒时间戳
  return Date.now() >= expirationTime;
};

2. 修改初始化逻辑

const accounts = msalInstance.getAllAccounts();

if (accounts.length > 0) {
  msalInstance.setActiveAccount(accounts[0]);
  const storedIdToken = localStorage.getItem('authStatus');
  
  // 若存储的令牌过期,触发刷新
  if (!storedIdToken || isIdTokenExpired(storedIdToken)) {
    refreshIdToken(msalInstance);
  }
}

三、优化MSAL配置(可选)

调整authConfig.js中的缓存策略,提升兼容性:

cache: {
  cacheLocation: "sessionStorage",
  storeAuthStateInCookie: true, // 隐私模式或跨域场景下开启Cookie存储
},

若后端需要特定权限,补充loginRequest的scopes:

export const loginRequest = {
  scopes: ["api://你的后端ClientId/access_as_user"], // 替换为实际权限范围
};

注意事项

  • 优先依赖MSAL实例获取令牌,而非仅依赖localStorage存储,避免令牌不一致。
  • 处理InteractionRequiredAuthError异常,引导用户重新完成身份验证。
  • 确保loginRequest的scopes与后端API要求的权限匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:15:01