Az MSAL React használatának első lépései

Ez a cikk végigvezeti azon, hogyan kezdheti el használni a(z) @azure/msal-react-t. Foglalkozunk az inicializálással, annak meghatározásával, hogy a felhasználó hitelesítve van-e, védi az összetevőket, bejelentkeztet egy felhasználót, és beszerez egy hozzáférési jogkivonatot.

Prerequisites

Inicializálás

@azure/msal-react a React környezeti API-ra épül, és az alkalmazás minden olyan részét, amely hitelesítést igényel, az MsalProvider összetevőbe kell csomagolni. Először inicializálnia kell egy PublicClientApplication példányt, majd ezt propként kell átadnia a MsalProvider számára.

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 />);

Az MsalProvider alatt lévő összes összetevő a kontextuson keresztül férhet hozzá a PublicClientApplication példányhoz, valamint az @azure/msal-reactáltal biztosított összes hookhoz és összetevőhöz.

Annak meghatározása, hogy a felhasználó hitelesítése megtörtént-e

A legtöbb alkalmazásnak feltételesen renderelnie kell bizonyos összetevőket attól függően, hogy egy felhasználó bejelentkezett-e vagy sem. @azure/msal-react 2 egyszerű módszert kínál erre.

AuthenticatedTemplate és UnauthenticatedTemplate

AuthenticatedTemplate és UnauthenticatedTemplate az összetevők csak akkor jelenítik meg a gyermekeiket, ha a felhasználó hitelesítése vagy hitelesítése nem történik meg.

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

A fenti burkolókomponensek alternatívájaként az alkalmazásod használhatja a useIsAuthenticated hookot. Erről az MSAL React Hooksban olvashat bővebben.

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>
    );
}

Összetevők védelme

Ha olyan összetevőkkel rendelkezik, amelyeket csak hitelesített felhasználóknak szeretne megjeleníteni, a fenti módszerek bármelyikét használhatja. De mi a teendő, ha automatikusan meg szeretné hívni a bejelentkezést, ha egy felhasználó még nincs hitelesítve? @azure/msal-react 2 módot biztosít erre a MsalAuthenticationTemplate vagy a useMsalAuthentication hook használatával.

MsalAuthenticationTemplate komponens

Az MsalAuthenticationTemplate összetevő megjeleníti a gyermekeket, ha egy felhasználót hitelesít, vagy megpróbál bejelentkezni. Csak adja meg a használni kívánt interakciótípust (átirányítás vagy előugró ablak), és opcionálisan egy kérésobjektumot , amelyet át kell adni a bejelentkezési API-nak, egy olyan összetevőt, amely a hitelesítés során jelenik meg, vagy egy összetevőt, amely hiba esetén jelenik meg.

Erre a lap bármelyik mintájában/profile talál egy működő példát.

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 horog

A useMsalAuthentication hook először ellenőrzi, hogy be van-e jelentkezve egy felhasználó, majd megpróbál bejelentkeztetni egy felhasználót, ha nincs bejelentkezett felhasználó. Meg kell adnia a használni kívánt interakciótípust (átirányítás vagy előugró ablak). Visszaadja a bejelentkezési művelet eredményét, a bekövetkezett hibákat és a bejelentkezési függvényt, amelyet akkor használhat, ha újra meg kell próbálkoznia.

Erről a horogról bővebben a horoggal kapcsolatos dokumentációban olvashat.

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>
    );
}

Felhasználó bejelentkezése az általa biztosított bejelentkezési API-k használatával @azure/msal-browser

A bejelentkezés kezdeményezésének egy másik módja, ha az @azure/msal-browser API-kat közvetlenül a kontextusban lévő PublicClientApplication példányból használja. A példányhoz 3 módon férhet hozzá a kontextusból.

useMsal hook

Egy hook, amely visszaadja a PublicClientApplication példányt, az összes jelenleg bejelentkezett fiókot tartalmazó tömböt, valamint egy inProgress értéket, amely megmondja, hogy az msal éppen mit csinál.

Erről a horogról bővebben a horoggal kapcsolatos dokumentációban olvashat.

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>
            </>
        );
    }
}

A nyers kontextus felhasználása

Ha osztályalapú komponenst használ, és nem tud hookokat használni, a nyers msal-környezetet a(z) MsalContext használatával érheti el. Az osztályösszetevők használatáról @azure/msal-reactitt olvashat bővebben.

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>
                </>
            );
        }
    }
}

A komponens becsomagolása a withMsal Higher-Order Componenttel

Az MSAL-környezet mind az osztály-, mind a függvénykomponensekben történő használatának egy másik módja, ha az összetevőt a withMsal HOC-kal csomagolja be, amely beilleszti a környezetet az összetevő propsai közé.

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);

Hozzáférési jogkivonat beszerzése

Javasoljuk, hogy az alkalmazás minden alkalommal hívja meg az acquireTokenSilent api-t az PublicClientApplication objektumon, amikor hozzáférési jogkivonatra van szüksége egy API eléréséhez. Ez az előző szakaszban leírt módszerekhez hasonlóan végezhető el.

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>
    }
}

Hozzáférési jogkivonat beszerzése a React-összetevőn kívül

Ha egy React-összetevőn kívüli hozzáférési jogkivonatra van szüksége, közvetlenül meghívhatja a acquireTokenSilent függvényt a PublicClientApplicationkövetkezőn: . Nem javasoljuk, hogy olyan függvényeket hívjon meg, amelyek megváltoztatják a felhasználó hitelesített állapotát (bejelentkezés, kijelentkezés) a reakciókörnyezeten MsalProvider kívül, mivel előfordulhat, hogy a környezeten belüli összetevők nem frissülnek megfelelően.

Ne feledje, hogy a jogkivonat beszerzése előtt be kell jelentkeznie a felhasználónak.

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
};

Lásd még