使用MSAL时应调用acquireTokenSilently还是将token存到localStorage?
React项目使用MSAL身份认证的最佳实践
关于token获取方式的结论
不要自行将token存储到localStorage复用,每次发起API请求前调用acquireTokenSilently获取token才是官方推荐的正确做法
为什么不建议自行存储token?
- MSAL内部已经实现了完善的缓存机制,默认会自动处理token的存储、读取、过期校验,不需要手动重复实现这部分逻辑
- 自行存储需要额外处理token过期刷新、多scope token匹配、权限变更等场景,很容易出现逻辑漏洞,比如token过期后请求报错、错用其他API的token导致鉴权失败
- 即使你配置MSAL使用localStorage作为缓存载体,也应该由MSAL自身操作存储,不要手动读写token值
为什么每次请求调用acquireTokenSilently没有性能问题?
- 该方法会优先查询MSAL的内部缓存,如果存在合法未过期的对应scope token,会直接返回本地缓存的结果,不会产生额外的网络请求
- 如果缓存token即将过期,MSAL会自动使用refresh token换取新的有效token,整个过程不需要手动处理
- 当静默获取失败(比如refresh token过期、用户权限被收回)时,会抛出固定的
InteractionRequiredAuthError错误,只需要统一捕获该错误触发用户交互登录即可,错误处理逻辑更统一
React项目MSAL落地最佳实践
- 优先使用官方提供的
@azure/msal-react封装库,不要自行基于@azure/msal-browser做底层封装,官方提供的Hooks已经覆盖了绝大多数场景 - 入口处用
MsalProvider包裹整个应用,全局共享MSAL实例 - 封装统一的请求拦截器(适配axios/fetch等请求工具),在拦截层统一执行token获取、请求头挂载、错误处理逻辑,不用每个请求单独写重复逻辑
参考实现代码(axios拦截器示例)
import { InteractionRequiredAuthError } from "@azure/msal-browser"; import { msalInstance } from "./msalConfig"; import axios from "axios"; const apiClient = axios.create({ baseURL: "你的业务API根地址", }); apiClient.interceptors.request.use(async (config) => { const activeAccount = msalInstance.getActiveAccount(); if (!activeAccount) return config; try { const tokenResponse = await msalInstance.acquireTokenSilent({ account: activeAccount, scopes: ["你申请的API访问Scope"], }); config.headers.Authorization = `Bearer ${tokenResponse.accessToken}`; } catch (err) { if (err instanceof InteractionRequiredAuthError) { // 静默获取失败,跳转到登录页或者弹出登录框 msalInstance.acquireTokenRedirect({ scopes: ["你申请的API访问Scope"], }); } throw err; } return config; }); export default apiClient;
内容的提问来源于stack exchange,提问作者Anchit Chawla
相关产品推荐
相关产品推荐

