Перехватчики в MSAL React

Хуки в MSAL React — это функции, которые позволяют использовать возможности MSAL, а также состояние React и методы его жизненного цикла внутри функциональных компонентов. Основными хуками являются useAccount, useIsAuthenticated, useMsal и useMsalAuthentication. В этой статье вы узнаете, как использовать каждый из этих крючков.

useAccount хук

Хук useAccount принимает параметр accountIdentifier и возвращает объект AccountInfo для этой учётной записи, если для неё выполнен вход, или null, если вход не выполнен. Если идентификатор учетной записи не указан, будет возвращена текущая активная учетная запись . Подробнее об объекте AccountInfo, возвращаемом в документации @azure/msal-browser, можно прочитать в разделе API входа в MSAL.

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, список учетных записей, в которые в данный момент выполнен вход, или если вам нужно знать, выполняется ли в данный момент вход или другое взаимодействие.

Примечание. Возвращаемое accountsuseMsal значение будет обновляться только при добавлении или удалении учетных записей и не будет обновляться при обновлении утверждений. Если вам нужен доступ к обновлённым утверждениям текущего пользователя, используйте хук 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) указывает, как вы хотите получить маркеры или имя входа при необходимости взаимодействия (обратите внимание, что параметр Silent имеет некоторые дополнительные рекомендации, описанные ниже).
  • объект запроса — (необязательно) указывает дополнительные параметры, которые используются при вызове входа в систему или получения токена.
  • accountIdentifiers — объект, используемый для указания хуку, какого пользователя следует авторизовать или для какого пользователя получать токены

Возвращаемые значения

  • результат — результат последнего успешного входа в систему или получения токена. Обратите внимание, что этот хук пытается автоматически выполнить вход или получить токены только один раз. При необходимости приложение несет ответственность за вызов login или acquireToken функцию, чтобы обновить это значение.
  • ошибка — Если при входе в систему или получении токена возникает ошибка, это свойство будет содержать сведения об ошибке. Чтобы повторить попытку, можно использовать функции login или acquireToken, возвращаемые этим хуком. Свойство error будет очищено при следующем успешном входе или получении токена.
  • login — функция, которую можно использовать для повтора неудачного входа. Свойства result и error будут обновлены.
  • acquireToken — функция, которую можно использовать для получения нового маркера доступа перед вызовом защищенного API. Свойства result и error будут обновлены.

Передача типа взаимодействия "Silent" вызовет ssoSilent, который попытается открыть скрытый iframe и повторно использовать существующий сеанс с Microsoft Entra ID. Это не будет работать в браузерах, которые блокируют сторонние файлы cookie, такие как Safari. Кроме того, объект запроса требуется при использовании типа Silent. Если у вас уже есть данные для входа пользователя, вы можете передать необязательный параметр 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>
    );
}

См. также

Документацию по API, предоставляемым PublicClientApplication, можно найти в MSAL Browser: