MSAL React 中的钩子是一些函数,可让你在函数组件中使用 MSAL 功能以及 React 的状态和生命周期方法。 主要的钩子是 useAccount、useIsAuthenticated、useMsal 和 useMsalAuthentication。 本文将带你了解这些钩子的用法。
useAccount 挂钩
useAccount 钩子接受一个 accountIdentifier 参数;如果该账户已登录,则返回该账户的 AccountInfo 对象,否则返回 null。 如果未提供帐户标识符,则返回当前 活动帐户 。
你可以在 @azure/msal-browser 文档的 MSAL 中的登录 API 一节中,进一步了解所返回的 AccountInfo 对象。
const accountIdentifier = {
localAccountId: "example-local-account-identifier",
homeAccountId: "example-home-account-identifier"
username: "example-username" // We do not recommend relying only on username
}
const accountInfo = useAccount(accountIdentifier);
useIsAuthenticated 挂钩
useIsAuthenticated挂钩返回一个布尔值,该值指示帐户是否已登录。 如果你需要知道某个特定账户是否已登录,它还可以可选地接受一个由你提供的 accountIdentifier 对象。
检查当前是否有任何账户已登录
以下代码片段使用 useIsAuthenticated 包中的 @azure/msal-react 挂钩。 然后,该组件根据用户是否登录有条件地呈现消息。
import React from 'react';
import { useIsAuthenticated } from "@azure/msal-react";
export function App() {
const isAuthenticated = useIsAuthenticated();
return (
<React.Fragment>
<p>Anyone can see this paragraph.</p>
{isAuthenticated && (
<p>At least one account is signed in!</p>
)}
{!isAuthenticated && (
<p>No users are signed in!</p>
)}
</React.Fragment>
);
}
确定特定用户是否已登录
以下代码片段使用 useIsAuthenticated 包中的 @azure/msal-react 挂钩来确定特定用户是否已登录。
import React from 'react';
import { useIsAuthenticated } from "@azure/msal-react";
export function App() {
const accountIdentifiers = {
localAccountId: "example-local-account-identifier",
homeAccountId: "example-home-account-identifier",
username: "example-username"
}
const isAuthenticated = useIsAuthenticated(accountIdentifiers);
return (
<React.Fragment>
<p>Anyone can see this paragraph.</p>
{isAuthenticated && (
<p>User with specified localAccountId is signed in!</p>
)}
{!isAuthenticated && (
<p>User with specified localAccountId is not signed in!</p>
)}
</React.Fragment>
);
}
useMsal 挂钩
useMsal挂钩返回上下文。 如果需要访问 PublicClientApplication 实例、当前已登录的帐户列表,或者是否需要知道登录名或其他交互当前是否正在进行,则可以使用此功能。
注意:由 useMsal 返回的 accounts 值仅会在添加或删除帐户时更新,而不会在声明更新时更新。 如果需要访问当前用户的更新声明,请改用 useAccount 挂钩或调用 acquireTokenSilent 。
import { useState, useEffect } from "react";
import { useMsal } from "@azure/msal-react";
import { InteractionStatus } from "@azure/msal-browser";
const { instance, accounts, inProgress } = useMsal();
const [loading, setLoading] = useState(false);
const [apiData, setApiData] = useState(null);
useEffect(() => {
if (!loading && inProgress === InteractionStatus.None && accounts.length > 0) {
if (apiData) {
// Skip data refresh if already set - adjust logic for your specific use case
return;
}
const tokenRequest = {
account: accounts[0], // This is an example - Select account based on your app's requirements
scopes: ["User.Read"]
}
// Acquire an access token
instance.acquireTokenSilent(tokenRequest).then((response) => {
// Call your API with the access token and return the data you need to save in state
callApi(response.accessToken).then((data) => {
setApiData(data);
setLoading(false);
});
}).catch(async (e) => {
// Catch interaction_required errors and call interactive method to resolve
if (e instanceof InteractionRequiredAuthError) {
await instance.acquireTokenRedirect(tokenRequest);
}
throw e;
});
}
}, [inProgress, accounts, instance, loading, apiData]);
if (loading || inProgress === InteractionStatus.Login) {
// Render loading component
} else if (apiData) {
// Render content that depends on data from your API
}
useMsalAuthentication 挂钩
useMsalAuthentication如果用户尚未登录,则挂钩将启动登录,否则它将尝试获取令牌。
输入参数
可以向 useMsalAuthentication 挂钩提供几个不同的输入参数:
- interactionType - (None、Popup、Redirect 或 Silent)指定在需要交互时如何获取令牌或登录名(请注意,静默选项有下面介绍的一些额外注意事项)。
- 请求对象 - (可选)指定登录或获取令牌调用要使用的其他参数
- accountIdentifiers - 用于告知该挂钩应为哪个用户登录或获取令牌的对象
返回值属性
-
result - 上次成功登录或获取令牌的结果。 请注意,此钩子仅会自动尝试登录或获取令牌一次。 应用程序负责在需要时调用
login或acquireToken函数来更新此值。 -
error - 如果在登录或令牌获取期间发生错误,此属性将包含有关错误的信息。 可以使用此挂钩返回的
login或acquireToken函数重试。 在下一次成功登录或令牌获取时,将清除该error属性。 -
login- 可用于重试失败登录的函数。result和error属性将会更新。 -
acquireToken- 在调用受保护的 API 之前,可用于获取新的访问令牌的函数。result和error属性将会被更新。
传递“静默”交互类型将调用 ssoSilent,该方法会尝试打开一个隐藏的 iframe,并复用与 Microsoft Entra ID 的现有会话。 这不适用于阻止第三方 Cookie(如 Safari)的浏览器。 此外,使用“无提示”类型时需要请求对象。 如果已有用户的登录信息,则可以传递 loginHint 或 sid 可选参数以登录特定帐户。 注意:还有其他 注意事项 - 使用 ssoSilent 时不提供有关用户会话的任何信息。
ssoSilent 示例
如果使用静默模式,应捕获任何错误,并尝试以交互方式登录作为备用方案。
import React, { useEffect } from 'react';
import { AuthenticatedTemplate, UnauthenticatedTemplate, useMsal, useMsalAuthentication } from "@azure/msal-react";
import { InteractionType, InteractionRequiredAuthError } from '@azure/msal-browser';
function App() {
const request = {
loginHint: "name@example.com",
scopes: ["User.Read"]
}
const { login, result, error } = useMsalAuthentication(InteractionType.Silent, request);
useEffect(() => {
if (error instanceof InteractionRequiredAuthError) {
login(InteractionType.Popup, request);
}
}, [error]);
const { accounts } = useMsal();
return (
<React.Fragment>
<p>Anyone can see this paragraph.</p>
<AuthenticatedTemplate>
<p>Signed in as: {accounts[0]?.username}</p>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>No users are signed in!</p>
</UnauthenticatedTemplate>
</React.Fragment>
);
}
export default App;
特定用户示例
如果要确保特定用户已登录,请提供一个 accountIdentifiers 对象。
import React from 'react';
import { useMsalAuthentication } from "@azure/msal-react";
import { InteractionType } from '@azure/msal-browser';
export function App() {
const accountIdentifiers = {
username: "example-username"
}
const request = {
loginHint: "example-username",
scopes: ["User.Read"]
}
const { login, result, error } = useMsalAuthentication(InteractionType.Popup, request, accountIdentifiers);
return (
<React.Fragment>
<p>Anyone can see this paragraph.</p>
<AuthenticatedTemplate username="example-username">
<p>Example user is signed in!</p>
</AuthenticatedTemplate>
<UnauthenticatedTemplate username="example-username">
<p>Example user is not signed in!</p>
</UnauthenticatedTemplate>
</React.Fragment>
);
}
另见
您可以在 MSAL Browser 中找到 PublicClientApplication 提供的 API 文档: