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
相关产品推荐
相关产品推荐

