Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo vai guiá-lo por como começar com @azure/msal-react. Vamos abordar a inicialização, a determinação se um utilizador está autenticado, a proteção dos componentes, o início de sessão do utilizador e a aquisição de um token de acesso.
Pré-requisitos
Inicialização
@azure/msal-react é construída sobre a API de contexto do React e todas as partes da sua aplicação que requerem autenticação devem estar integradas no MsalProvider componente. Primeiro terás de inicializar uma instância de PublicClientApplication e depois passar isso como MsalProvider prop.
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 />);
Todos os componentes abaixo de MsalProvider terão acesso à instância PublicClientApplication através do contexto, assim como todos os hooks e componentes fornecidos por @azure/msal-react.
Determinar se um utilizador está autenticado
A maioria das aplicações terá de renderizar condicionalmente certos componentes consoante o utilizador tenha ou não sessão iniciada.
@azure/msal-react Fornece 2 formas simples de fazer isto.
AuthenticatedTemplate e UnauthenticatedTemplate
AuthenticatedTemplate e UnauthenticatedTemplate os componentes só renderizam os seus filhos se um utilizador estiver autenticado ou não autenticado, respetivamente.
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 gancho
Como alternativa aos componentes do wrapper acima, a sua aplicação pode usar o useIsAuthenticated gancho. Pode ler mais sobre isto em Hooks no 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>
);
}
Componentes de Proteção
Se tens componentes que só queres mostrar a utilizadores autenticados, podes usar qualquer um dos métodos acima. Mas e se quiser invocar automaticamente um login se um utilizador ainda não estiver autenticado?
@azure/msal-react fornece duas formas de o fazer com o hook MsalAuthenticationTemplate ou com o hook useMsalAuthentication.
MsalAuthenticationTemplate componente
O MsalAuthenticationTemplate componente irá renderizar os seus filhos se um utilizador for autenticado ou tentar iniciar sessão com um utilizador. Basta fornecer-lhe o tipo de interação que pretende usar (redirecionar ou popup) e, opcionalmente, um objeto de pedido para ser passado à API de login, um componente para mostrar enquanto a autenticação está em curso ou um componente para mostrar caso ocorra um erro.
Pode encontrar um exemplo funcional disto em qualquer um dos nossos exemplos na /profile página.
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 gancho
O hook useMsalAuthentication verifica primeiro se um utilizador tem sessão iniciada e, em seguida, tenta iniciar a sessão de um utilizador se não houver utilizadores com sessão iniciada. Terá de fornecer o tipo de interação que gostaria de usar (redirecionar ou pop-up).
Vai devolver o resultado da operação de login, qualquer erro que tenha ocorrido e a função de login que pode usar se precisar de tentar novamente.
Pode ler mais sobre este hook na documentação sobre hooks.
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>
);
}
Iniciar sessão de um utilizador usando as APIs de login fornecidas por @azure/msal-browser
Outra forma de invocar um início de sessão é utilizando diretamente as APIs @azure/msal-browser a partir da instância PublicClientApplication no contexto. Existem 3 formas de aceder à instância a partir do contexto.
useMsal gancho
Um hook que devolve a instância PublicClientApplication, um array com todas as contas com sessão iniciada atualmente e um valor inProgress que indica o que o MSAL está atualmente a fazer.
Pode ler mais sobre este hook na documentação sobre hooks.
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>
</>
);
}
}
Utilizar o contexto bruto
Se estiveres a usar um componente de classe e não puderes usar hooks, podes consumir o contexto MSAL em bruto através de MsalContext.
Pode ler mais sobre como usar @azure/msal-react em componentes de classe aqui.
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>
</>
);
}
}
}
Encapsular o seu componente com o withMsal componente de ordem superior
Outra forma de consumir o contexto MSAL tanto em componentes em classe como em componentes funcionais é envolver o seu componente com o HOC withMsal, que injeta o contexto nas propriedades do seu componente.
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);
Aquisição de um token de acesso
Recomendamos que a sua aplicação chame a acquireTokenSilent API do seu PublicClientApplication objeto sempre que precisar de um token de acesso para aceder a uma API. Isto pode ser feito de forma semelhante às formas descritas na secção anterior.
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>
}
}
Aquisição de um token de acesso fora de um componente React
Se precisar de um token de acesso fora de um componente React, pode chamar diretamente a acquireTokenSilent função no PublicClientApplication.
Não recomendamos chamar funções que alterem o estado autenticado do utilizador (login, logout) fora do contexto react fornecido por por MsalProvider , pois os componentes dentro do contexto podem não ser atualizados corretamente.
Tenha em mente que o utilizador tem de ter iniciado sessão antes de poder obter um token.
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
};
Consulte também
- Consulte o nosso exemplo de router react para um exemplo funcional.
- Utilização do MSAL React com componentes de classe