如何基于@azure/msal-react实现Access Token自动刷新?
实现@azure/msal-react中Access Token自动刷新的方案
@azure/msal-react 基于 @azure/msal-browser,本身内置了token自动刷新能力,只要配置和使用方式正确,就能自动处理access token的过期刷新。以下是具体实现步骤:
1. 确保依赖版本与基础配置正确
- 保持
@azure/msal-react和@azure/msal-browser为最新稳定版本,避免旧版本的已知bug。 - 初始化MSAL实例时,配置持久化缓存(推荐
localStorage),确保refresh token在页面刷新后依然可用于刷新access token:
import { PublicClientApplication } from "@azure/msal-browser"; const msalConfig = { auth: { clientId: "你的客户端ID", authority: "https://login.microsoftonline.com/你的租户ID", redirectUri: "你的重定向地址" }, cache: { cacheLocation: "localStorage", // 持久化存储refresh token storeAuthStateInCookie: false // 仅需兼容IE时开启 } }; const msalInstance = new PublicClientApplication(msalConfig);
2. 通过acquireTokenSilent自动处理token刷新
不要直接从缓存中读取access token,每次需要使用token时,调用acquireTokenSilent方法。该方法会自动检查token状态:
- 如果token未过期,直接返回缓存中的token;
- 如果token过期但存在有效refresh token,自动静默刷新access token;
- 如果refresh token也过期(比如用户长时间未操作),则抛出
InteractionRequiredAuthError,此时可触发交互式登录。
示例组件代码:
import { useMsal, InteractionRequiredAuthError } from "@azure/msal-react"; function ApiCallingComponent() { const { instance, accounts } = useMsal(); const activeAccount = accounts[0]; const fetchProtectedData = async () => { try { // 静默获取/刷新access token const tokenResponse = await instance.acquireTokenSilent({ account: activeAccount, scopes: ["https://graph.microsoft.com/User.Read"] // 需与授权时的scopes一致 }); // 使用token调用API const response = await fetch("你的受保护API地址", { headers: { Authorization: `Bearer ${tokenResponse.accessToken}` } }); const data = await response.json(); // 处理返回数据 } catch (error) { if (error instanceof InteractionRequiredAuthError) { // 静默刷新失败,触发重定向登录 instance.acquireTokenRedirect({ account: activeAccount, scopes: ["https://graph.microsoft.com/User.Read"] }); } else { console.error("获取token失败:", error); } } }; return <button onClick={fetchProtectedData}>获取受保护数据</button>; }
3. 可选:监听token过期事件提前刷新
可以通过MSAL的事件监听机制,在access token过期时主动触发静默刷新:
import { EventType } from "@azure/msal-browser"; // 初始化MSAL实例后添加事件监听 msalInstance.addEventCallback((event) => { if (event.eventType === EventType.ACCESS_TOKEN_EXPIRED) { const activeAccount = msalInstance.getActiveAccount(); if (activeAccount) { msalInstance.acquireTokenSilent({ account: activeAccount, scopes: ["你的API权限范围"] }).catch(err => { if (err instanceof InteractionRequiredAuthError) { msalInstance.acquireTokenRedirect({ account: activeAccount, scopes: ["你的API权限范围"] }); } }); } } });
注意事项
- 确保应用注册中配置了正确的API权限,且refresh token的有效期符合需求(微软默认refresh token有效期为90天,且会在使用时滚动刷新);
- 不要手动存储或管理access token,完全交由MSAL的缓存机制处理,避免出现token不一致问题。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

