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

共用Azure应用注册的React SPA遇MSAL多匹配ID Token缓存错误求助

解决MSAL多匹配IdToken错误(multiple_matching_tokens)

问题背景

两个React(v18) SPA应用共用同一Azure AD应用注册,使用@azure/msal-browser: 2.32.2和@azure/msal-react: 1.5.2,单独打开应用功能正常,但同时使用时触发以下错误:

ClientAuthError: multiple_matching_tokens: The cache contains multiple tokens satisfying the requirements. Call AcquireToken again providing more requirements such as authority or account..
at t [as constructor] (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:328717)
at new t (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:340847)
at t.createMultipleMatchingTokensInCacheError (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:342380)
at e.readIdTokenFromCache (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:408459)
at /aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:401953
at Array.map ()
at e.getAllAccounts (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:401888)
at e.getAllAccounts (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:615681)
at lc (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:630671)
at Object.ja [as useReducer] (/aircraft-ui/main.b9f4f91dd3e752cc.esm.js:2:1967211)

核心原因

两个应用共享同一Client ID,MSAL默认基于Client ID和Authority生成缓存键,导致浏览器缓存中的token被两个应用共享。当其中一个应用尝试读取缓存中的IdToken或获取账户时,MSAL无法区分目标token所属的应用,因此抛出多匹配错误。

解决方案

1. 为每个应用配置独立的缓存键

修改MSAL实例的缓存配置,给每个应用设置唯一的cacheKey,让它们拥有独立的缓存空间:

// 应用1的MSAL配置
const msalConfigApp1 = {
  auth: {
    clientId: "你的共享Client ID",
    authority: "https://login.microsoftonline.com/你的租户ID",
    redirectUri: "应用1的重定向URI"
  },
  cache: {
    cacheLocation: "sessionStorage", // 推荐用sessionStorage减少跨标签页干扰
    cacheKey: "app1-unique-cache-key" // 每个应用设置不同的唯一值
  }
};

const msalInstanceApp1 = new PublicClientApplication(msalConfigApp1);
// 应用2的MSAL配置
const msalConfigApp2 = {
  auth: {
    clientId: "你的共享Client ID",
    authority: "https://login.microsoftonline.com/你的租户ID",
    redirectUri: "应用2的重定向URI"
  },
  cache: {
    cacheLocation: "sessionStorage",
    cacheKey: "app2-unique-cache-key" // 与应用1不同的唯一值
  }
};

const msalInstanceApp2 = new PublicClientApplication(msalConfigApp2);

2. 明确指定请求的账户参数

在调用acquireTokenSilent或获取账户时,明确传入目标账户信息,避免MSAL匹配多个token:

// 获取指定账户
const targetAccount = msalInstance.getAccountByUsername("user@your-domain.com");
// 或者通过homeAccountId获取
// const targetAccount = msalInstance.getAccountByHomeId("用户的homeAccountId");

// 静默获取token时指定账户
const tokenRequest = {
  scopes: ["user.read"],
  account: targetAccount // 明确指定账户
};

try {
  const response = await msalInstance.acquireTokenSilent(tokenRequest);
} catch (error) {
  // 处理静默获取失败,比如弹出登录窗口
  await msalInstance.acquireTokenPopup(tokenRequest);
}

3. 在msal-react组件中筛选目标账户

使用useMsal钩子时,主动筛选出当前应用对应的账户:

import { useMsal } from "@azure/msal-react";

function MyComponent() {
  const { accounts, instance } = useMsal();
  // 根据用户名或homeAccountId筛选目标账户
  const currentAccount = accounts.find(acc => acc.username === "expected-user@domain.com");

  // 使用currentAccount进行后续操作
  return <div>当前用户:{currentAccount?.username}</div>;
}

可选:升级MSAL版本

旧版本MSAL可能存在缓存处理的兼容性问题,建议升级到@azure/msal-browser和@azure/msal-react的最新稳定版(如v2.x的最新版或v3.x系列),新版本对多应用共享Client ID的场景有更好的支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:30:49