Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come iniziare a usare @azure/msal-react. Verrà illustrata l'inizializzazione, determinando se un utente è autenticato, proteggendo i componenti, firmando un utente in e acquisendo un token di accesso.
Prerequisiti
Inizializzazione
@azure/msal-react è basato sulla API del contesto React e tutte le parti della tua app che richiedono l'autenticazione devono essere racchiuse nel componente MsalProvider. Sarà prima necessario inizializzare un'istanza di PublicClientApplication e quindi passarla a MsalProvider come 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 />);
Tutti i componenti sottostanti MsalProvider avranno accesso all'istanza di PublicClientApplication tramite contesto, nonché tutti gli hook e i componenti forniti da @azure/msal-react.
Determinare se un utente è autenticato
La maggior parte delle applicazioni dovrà visualizzare determinati componenti in modo condizionale, a seconda che un utente abbia effettuato l'accesso oppure no.
@azure/msal-react offre 2 modi semplici per eseguire questa operazione.
AuthenticatedTemplate e UnauthenticatedTemplate
I componenti AuthenticatedTemplate e UnauthenticatedTemplate renderizzeranno i rispettivi elementi figlio solo se un utente è autenticato o non autenticato, rispettivamente.
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 hook
In alternativa ai componenti wrapper sopra la tua app, puoi usare l'hook useIsAuthenticated . Puoi leggere ulteriori informazioni al riguardo in Hooks in 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>
);
}
Protezione dei componenti
Se si dispone di componenti da mostrare solo agli utenti autenticati, è possibile usare uno dei metodi precedenti. Ma cosa accade se si vuole richiamare automaticamente un account di accesso se un utente non è ancora autenticato?
@azure/msal-react offre 2 modi per farlo con l'hook MsalAuthenticationTemplate o l'hook useMsalAuthentication.
Componente MsalAuthenticationTemplate
Il componente MsalAuthenticationTemplate eseguirà il rendering dei suoi elementi figlio se un utente è autenticato oppure tenterà di effettuare l'accesso dell'utente. È sufficiente fornire il tipo di interazione che si vuole usare (reindirizzamento o popup) e, facoltativamente, un oggetto richiesta da passare all'API di accesso, un componente da visualizzare mentre l'autenticazione è in corso o un componente da visualizzare se si verifica un errore.
È possibile trovare un esempio funzionante di questo in uno dei nostri esempi nella /profile pagina.
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 hook
L'hook useMsalAuthentication verifica prima se un utente ha effettuato l'accesso, quindi tenta di far accedere un utente se nessun utente ha effettuato l'accesso. Dovrai fornire il tipo di interazione che vuoi usare (reindirizzamento o popup).
Restituisce il risultato dell'operazione di accesso, qualsiasi errore che si è verificato e la funzione di accesso che è possibile usare se è necessario riprovare.
Per altre informazioni su questo hook, vedere la documentazione sugli hook.
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>
);
}
Effettuare l'accesso di un utente usando le API di accesso fornite da @azure/msal-browser
Un altro modo per avviare l'accesso consiste nell'usare direttamente le API @azure/msal-browser dall'istanza PublicClientApplication presente nel contesto. Esistono tre modi per accedere all'istanza dal contesto.
useMsal Gancio
Un hook che restituisce l'istanza PublicClientApplication, un array di tutti gli account che hanno attualmente effettuato l'accesso e un valore inProgress che indica cosa sta facendo attualmente msal.
Per altre informazioni su questo hook, vedere la documentazione sugli hook.
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>
</>
);
}
}
Utilizzo del contesto non elaborato
Se si usa un componente di classe e non è possibile usare hook, è possibile utilizzare il contesto msal non elaborato tramite MsalContext.
Per altre informazioni sull'uso @azure/msal-react dei componenti di classe, vedere qui.
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>
</>
);
}
}
}
Avvolgere il tuo componente con il withMsal componente di ordine superiore
Un altro modo per usare il contesto MSAL sia nei componenti di classe sia in quelli funzione consiste nel racchiudere il componente con l'HOC withMsal, che inserirà il contesto nelle props del tuo 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);
Acquisizione di un token di accesso
È consigliabile che l'app chiami l'API nell'oggetto acquireTokenSilentPublicClientApplication ogni volta che è necessario un token di accesso per accedere a un'API. Questa operazione può essere eseguita in modo simile ai modi descritti nella sezione precedente.
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>
}
}
Acquisizione di un token di accesso all'esterno di un componente React
Se è necessario un token di accesso all'esterno di un componente React, è possibile chiamare direttamente la acquireTokenSilent funzione in PublicClientApplication.
Non è consigliabile chiamare funzioni che modificano lo stato autenticato dell'utente (account di accesso, disconnessione) all'esterno del contesto react fornito da MsalProvider poiché i componenti all'interno del contesto potrebbero non essere aggiornati correttamente.
Tenere presente che l'utente deve essere connesso prima di poter acquisire un 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
};
Vedere anche
- Consulta il nostro esempio di React Router per un esempio funzionante.
- Uso di MSAL React con componenti di classe