Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье вы узнаете, как приступить к работе с @azure/msal-react. Мы рассмотрим инициализацию, определение подлинности пользователя, защиту компонентов, вход пользователя и получение маркера доступа.
Необходимые условия
Инициализация
@azure/msal-react основан на API контекста React, и все части вашего приложения, которым требуется аутентификация, должны быть обёрнуты в компонент MsalProvider. Сначала вам нужно инициализировать экземпляр PublicClientApplication, а затем передать его в MsalProvider как свойство.
import React from "react";
import { createRoot } from "react-dom/client";
import { MsalProvider } from "@azure/msal-react";
import { Configuration, PublicClientApplication } from "@azure/msal-browser";
import App from "./app.jsx";
// MSAL configuration
const configuration: Configuration = {
auth: {
clientId: "client-id"
}
};
const pca = new PublicClientApplication(configuration);
// Component
const AppProvider = () => (
<MsalProvider instance={pca}>
<App />
</MsalProvider>
);
const root = createRoot(document.getElementById("root"));
root.render(<AppProvider />);
Все компоненты под MsalProvider будут иметь доступ к экземпляру PublicClientApplication через контекст, а также ко всем хукам и компонентам, предоставляемым @azure/msal-react.
Определение того, аутентифицирован ли пользователь
Большинству приложений потребуется условно отображать определённые компоненты в зависимости от того, вошёл пользователь в систему или нет.
@azure/msal-react предоставляет 2 простых способа сделать это.
AuthenticatedTemplate и UnauthenticatedTemplate.
Компоненты AuthenticatedTemplate и UnauthenticatedTemplate будут отображать свои дочерние элементы только в том случае, если пользователь аутентифицирован или, соответственно, не аутентифицирован.
import React from 'react';
import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-react";
export function App() {
return (
<React.Fragment>
<p>Anyone can see this paragraph.</p>
<AuthenticatedTemplate>
<p>At least one account is signed in!</p>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>No users are signed in!</p>
</UnauthenticatedTemplate>
</React.Fragment>
);
}
useIsAuthenticated хук
В качестве альтернативы указанным выше компонентам-обёрткам ваше приложение может использовать хук useIsAuthenticated. Дополнительные сведения об этом см. в разделе "Перехватчики" в 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>
);
}
Защита компонентов
Если у вас есть компоненты, которые вы хотите отображать только для пользователей, прошедших проверку подлинности, можно использовать любой из описанных выше методов. Но что делать, если вы хотите автоматически вызвать имя входа, если пользователь еще не прошел проверку подлинности?
@azure/msal-react предусматривает 2 способа сделать это: с помощью MsalAuthenticationTemplate или хука useMsalAuthentication.
Компонент MsalAuthenticationTemplate
Компонент MsalAuthenticationTemplate отображает свои дочерние элементы, если пользователь аутентифицирован, или пытается выполнить вход пользователя в систему. Просто укажите для него тип взаимодействия, который вы хотите использовать (перенаправление или всплывающее окно), и при необходимости объект запроса, который будет передан в API входа, компонент для отображения во время выполнения аутентификации или компонент для отображения в случае возникновения ошибки.
Вы можете найти рабочий пример этого в любом из наших примеров на /profile странице.
import React from "react";
import { MsalAuthenticationTemplate } from "@azure/msal-react";
import { InteractionType } from "@azure/msal-browser";
function ErrorComponent({error}) {
return <p>An Error Occurred: {error}</p>;
}
function LoadingComponent() {
return <p>Authentication in progress...</p>;
}
export function Example() {
const authRequest = {
scopes: ["openid", "profile"]
};
return (
// authenticationRequest, errorComponent and loadingComponent props are optional
<MsalAuthenticationTemplate
interactionType={InteractionType.Popup}
authenticationRequest={authRequest}
errorComponent={ErrorComponent}
loadingComponent={LoadingComponent}
>
<p>At least one account is signed in!</p>
</MsalAuthenticationTemplate>
)
};
useMsalAuthentication хук
Хук useMsalAuthentication сначала проверит, вошёл ли пользователь в систему, а затем попытается выполнить вход пользователя, если ни один пользователь не вошёл в систему. Необходимо указать тип взаимодействия, который вы хотите использовать (перенаправление или всплывающее окно).
Он вернет результат операции входа, любую ошибку, которая произошла, и функцию входа, которую можно использовать, если необходимо повторить попытку.
Дополнительные сведения об этом хуке см. в документации по хукам.
import React from 'react';
import { useMsalAuthentication } from "@azure/msal-react";
import { InteractionType } from '@azure/msal-browser';
export function App() {
const {login, result, error} = useMsalAuthentication(InteractionType.Popup);
return (
<React.Fragment>
<p>Anyone can see this paragraph.</p>
<AuthenticatedTemplate>
<p>At least one account is signed in!</p>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>No users are signed in!</p>
</UnauthenticatedTemplate>
</React.Fragment>
);
}
Выполните вход пользователя с помощью API для входа, предоставляемых @azure/msal-browser
Другой способ инициировать вход — использовать API @azure/msal-browser напрямую из экземпляра PublicClientApplication в контексте. Существует 3 способа доступа к экземпляру из контекста.
useMsal хук
Хук, который возвращает экземпляр PublicClientApplication, массив всех учетных записей, выполнивших вход в систему, и значение inProgress, показывающее, что msal делает в данный момент.
Дополнительные сведения об этом хуке см. в документации по хукам.
import React from 'react';
import { useMsal } from "@azure/msal-react";
export function App() {
const { instance, accounts, inProgress } = useMsal();
if (accounts.length > 0) {
return <span>There are currently {accounts.length} users signed in!</span>
} else if (inProgress === "login") {
return <span>Login is currently in progress!</span>
} else {
return (
<>
<span>There are currently no users signed in!</span>
<button onClick={() => instance.loginPopup()}>Login</button>
</>
);
}
}
Использование необработанного контекста
Если вы используете классовый компонент и не можете использовать хуки, вы можете получить доступ к исходному контексту MSAL через MsalContext.
Дополнительные сведения об использовании @azure/msal-react компонентов класса см. здесь.
import React from "react";
import { MsalContext } from "@azure/msal-react";
class App extends React.Component {
static contextType = MsalContext;
render() {
if (this.context.accounts.length > 0) {
return <span>There are currently {this.context.accounts.length} users signed in!</span>
} else if (this.context.inProgress === "login") {
return <span>Login is currently in progress!</span>
} else {
return (
<>
<span>There are currently no users signed in!</span>
<button onClick={() => this.context.instance.loginPopup()}>Login</button>
</>
);
}
}
}
Обертывание вашего компонента в withMsalкомпонент высшего порядка
Другой способ использовать контекст MSAL как в классовых, так и в функциональных компонентах — обернуть компонент в withMsal HOC, который будет передавать контекст в свойства вашего компонента.
import React from "react";
import { withMsal } from "@azure/msal-react";
class LoginButton extends React.Component {
render() {
const isAuthenticated = this.props.msalContext.accounts.length > 0;
const msalInstance = this.props.msalContext.instance;
if (isAuthenticated) {
return <button onClick={() => msalInstance.logout()}>Logout</button>
} else {
return <button onClick={() => msalInstance.loginPopup()}>Login</button>
}
}
}
export default YourWrappedComponent = withMsal(LoginButton);
Получение токена доступа
Мы рекомендуем приложению вызывать acquireTokenSilent API в объекте PublicClientApplication каждый раз, когда вам нужен маркер доступа для доступа к API. Это можно сделать примерно так, как описано в предыдущем разделе.
import React, { useState, useEffect } from "react"
import { useMsal, useAccount } from "@azure/msal-react";
export function App() {
const { instance, accounts, inProgress } = useMsal();
const account = useAccount(accounts[0] || {});
const [apiData, setApiData] = useState(null);
useEffect(() => {
if (account) {
instance.acquireTokenSilent({
scopes: ["User.Read"],
account: account
}).then((response) => {
if(response) {
callMsGraph(response.accessToken).then((result) => setApiData(result));
}
});
}
}, [account, instance]);
if (accounts.length > 0) {
return (
<>
<span>There are currently {accounts.length} users signed in!</span>
{apiData && (<span>Data retreived from API: {JSON.stringify(apiData)}</span>)}
</>
);
} else if (inProgress === "login") {
return <span>Login is currently in progress!</span>
} else {
return <span>There are currently no users signed in!</span>
}
}
Получение токена доступа за пределами компонента React
Если вам нужен маркер доступа за пределами компонента React, вы можете напрямую вызвать функцию acquireTokenSilent у объекта PublicClientApplication.
Мы не рекомендуем вызывать функции, изменяющие состояние аутентификации пользователя (вход, выход), за пределами контекста React, предоставляемого MsalProvider, поскольку компоненты внутри этого контекста могут обновляться некорректно.
Помните, что пользователь должен войти в систему, прежде чем получить токен.
import { PublicClientApplication } from "@azure/msal-browser";
// This should be the same instance you pass to MsalProvider
const msalInstance = new PublicClientApplication(config);
const acquireAccessToken = async (msalInstance) => {
const activeAccount = msalInstance.getActiveAccount(); // This will only return a non-null value if you have logic somewhere else that calls the setActiveAccount API
const accounts = msalInstance.getAllAccounts();
if (!activeAccount && accounts.length === 0) {
/*
* User is not signed in. Throw error or wait for user to login.
* Do not attempt to log a user in outside of the context of MsalProvider
*/
}
const request = {
scopes: ["User.Read"],
account: activeAccount || accounts[0]
};
const authResult = await msalInstance.acquireTokenSilent(request);
return authResult.accessToken
};
См. также
- Ознакомьтесь с примером маршрутизатора React для рабочего примера.
- Использование MSAL React с компонентами класса