适用于: 员工租户
外部租户(了解详细信息)
使用 MSAL.js 获取 API 令牌的模式是首先尝试通过acquireTokenSilent
方法进行静默令牌请求。 调用此方法时,该库会首先检查浏览器存储中的缓存,看是否存在未过期的访问令牌,在有的情况下会将其返回。 如果未找到访问令牌或找到的访问令牌已过期,它将尝试使用其刷新令牌来获取新的访问令牌。 如果刷新令牌的 24 小时生存期也已过期,MSAL.js 会打开一个隐藏的 iframe,以通过适用于与 Microsoft Entra ID 的现有活动会话(如果有)按无提示方式请求新的授权代码,然后使用这些代码交换一组新令牌(访问和刷新令牌)。
有关 Microsoft Entra ID 中的单一登录 (SSO) 会话和令牌生存期值的详细信息,请参阅令牌生存期。 有关 MSAL.js 缓存查找策略的详细信息,请参阅:获取访问令牌。
可能会因某些原因(例如密码更改,或者更新的条件访问策略)而导致以无提示方式向 Microsoft Entra ID 请求令牌失败。 而失败更常见的原因是刷新令牌的 24 小时生存期已过期以及浏览器阻止第三方 Cookie,这会阻止使用隐藏的 Iframe 继续对用户进行身份验证。 在这些情况下,应调用其中一个交互式方法(可能会提示用户)来获取令牌:
在弹出窗口或重定向体验之间进行选择
在弹出窗口和重定向体验之间进行的选择取决于应用程序流:
- 如果不希望用户在身份验证期间离开主应用程序页,建议使用弹出窗口方法。 由于身份验证重定向发生在弹出窗口中,系统会保留主应用程序的状态。
- 如果用户的浏览器约束或策略禁用了弹出窗口,则可使用重定向方法。 请使用重定向方法,因为 Internet Explorer 浏览器弹出窗口存在已知问题。
可以设置在生成访问令牌请求时希望访问令牌包含的 API 范围。 可能不会在访问令牌中授予所有请求的范围。 具体取决于用户的许可。
通过弹出窗口获取令牌
以下代码将前面描述的模式与弹出体验的方法结合起来:
import {
InteractionRequiredAuthError,
InteractionStatus,
} from "@azure/msal-browser";
import { AuthenticatedTemplate, useMsal } from "@azure/msal-react";
function ProtectedComponent() {
const { instance, inProgress, accounts } = useMsal();
const [apiData, setApiData] = useState(null);
useEffect(() => {
if (!apiData && inProgress === InteractionStatus.None) {
const accessTokenRequest = {
scopes: ["user.read"],
account: accounts[0],
};
instance
.acquireTokenSilent(accessTokenRequest)
.then((accessTokenResponse) => {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken).then((response) => {
setApiData(response);
});
})
.catch((error) => {
if (error instanceof InteractionRequiredAuthError) {
instance
.acquireTokenPopup(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token interactive success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken).then((response) => {
setApiData(response);
});
})
.catch(function (error) {
// Acquire token interactive failure
console.log(error);
});
}
console.log(error);
});
}
}, [instance, accounts, inProgress, apiData]);
return <p>Return your protected content here: {apiData}</p>;
}
function App() {
return (
<AuthenticatedTemplate>
<ProtectedComponent />
</AuthenticatedTemplate>
);
}
或者,如果需要在 React 组件的外部获取令牌,可以调用 acquireTokenSilent
,但如果失败,则不应回退到交互。 所有交互都应在组件树中的 MsalProvider
组件下进行。
// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];
const accessTokenRequest = {
scopes: ["user.read"],
account: account,
};
// Use the same publicClientApplication instance provided to MsalProvider
publicClientApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
//Acquire token silent failure
console.log(error);
});
通过重定向获取令牌
如果 acquireTokenSilent
失败,则回退到 acquireTokenRedirect
。 此方法将启动全帧重定向,并在响应返回到应用程序时对其进行处理。 在从重定向返回后呈现此组件时,acquireTokenSilent
应该会成功,因为将从缓存中拉取令牌。
import {
InteractionRequiredAuthError,
InteractionStatus,
} from "@azure/msal-browser";
import { AuthenticatedTemplate, useMsal } from "@azure/msal-react";
function ProtectedComponent() {
const { instance, inProgress, accounts } = useMsal();
const [apiData, setApiData] = useState(null);
useEffect(() => {
const accessTokenRequest = {
scopes: ["user.read"],
account: accounts[0],
};
if (!apiData && inProgress === InteractionStatus.None) {
instance
.acquireTokenSilent(accessTokenRequest)
.then((accessTokenResponse) => {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken).then((response) => {
setApiData(response);
});
})
.catch((error) => {
if (error instanceof InteractionRequiredAuthError) {
instance.acquireTokenRedirect(accessTokenRequest);
}
console.log(error);
});
}
}, [instance, accounts, inProgress, apiData]);
return <p>Return your protected content here: {apiData}</p>;
}
function App() {
return (
<AuthenticatedTemplate>
<ProtectedComponent />
</AuthenticatedTemplate>
);
}
或者,如果需要在 React 组件的外部获取令牌,可以调用 acquireTokenSilent
,但如果失败,则不应回退到交互。 所有交互都应在组件树中的 MsalProvider
组件下进行。
// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];
const accessTokenRequest = {
scopes: ["user.read"],
account: account,
};
// Use the same publicClientApplication instance provided to MsalProvider
publicClientApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
//Acquire token silent failure
console.log(error);
});