Utilização do MSAL React com componentes de classe

O MSAL React suporta tanto componentes funcionais como componentes de classe. Este artigo fornece orientações sobre a utilização do MSAL React com componentes de classe, permitindo-lhe inicializar, proteger e aceder ao contexto do MSAL React nos seus componentes de classe.

É importante notar que não vai poder usar hooks @azure/msal-react nos seus componentes de classe. Se precisar de acesso ao estado de autenticação dentro do seu componente de classe, terá de usar @azure/msal-browser diretamente para obter funcionalidades semelhantes.

Pré-requisitos

Inicialização

A inicialização com componentes de classe com MSAL React funciona de forma muito semelhante à inicialização com componentes funcionais. Tal como ao usar componentes de função, vai precisar de um MsalProvider componente no nível superior da árvore de componentes que exija acesso ao estado de autenticação.

No excerto seguinte, o componente MsalProvider é utilizado para envolver toda a aplicação, disponibilizando a instância MSAL a todos os componentes filhos. Isto permite que os componentes filhos utilizem o MSAL para autenticação de utilizadores, obtenção de tokens e chamar APIs protegidas.

import React from "react";
import { MsalProvider } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);

class App extends React.Component {
    render() {
        return (
            <MsalProvider instance={pca}>
                <YourAppComponents>
            </ MsalProvider>
        );
    }
}

Componentes de Proteção

No MSAL React, podes proteger os teus componentes e renderizá-los condicionalmente com base no estado de autenticação do utilizador. Isto funciona de forma semelhante à utilização de componentes funcionais. Os principais exemplos são:

  • AuthenticatedTemplate - Este componente só renderizará os seus filhos se o utilizador estiver autenticado. Se o utilizador não estiver autenticado, não irá renderizar nada.
  • UnauthenticatedTemplate - Este componente só renderizará os seus filhos se o utilizador não estiver autenticado. Se o utilizador estiver autenticado, não irá renderizar nada.
  • MsalAuthenticationTemplate - Este componente tenta autenticar o utilizador antes de renderizar os seus filhos. Podes especificar o tipo de interação (redirecionamento ou popup) como um prop. Se o utilizador não estiver autenticado, iniciará o processo de autenticação.

O excerto seguinte mostra como usar AuthenticatedTemplate, UnauthenticatedTemplate, e MsalAuthenticationTemplate proteger os seus componentes React. Repare como MSAL Provider se enrola à volta dos componentes filhos.

import React from "react";
import { MsalProvider, AuthenticatedTemplate, UnauthenticatedTemplate, MsalAuthenticationTemplate } from "@azure/msal-react";
import { PublicClientApplication, InteractionType } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);

class App extends React.Component {
    render() {
        return (
            <MsalProvider instance={pca}>
                <AuthenticatedTemplate>
                    <span>This will only render for authenticated users</span>
                </ AuthenticatedTemplate>
                <UnauthenticatedTemplate>
                    <span>This will only render for unauthenticated users</span>
                </ UnauthenticatedTemplate>
                <MsalAuthenticationTemplate interactionType={InteractionType.Popup}>
                    <span>This will only render for authenticated users.</span>
                </ MsalAuthenticationTemplate>
            </ MsalProvider>
        );
    }
}

Aceder ao contexto MSAL React num componente de classe

O useMsal gancho não pode ser usado para aceder ao contexto MSAL React num componente de classe. Isto porque os ganchos só podem ser usados em componentes funcionais, onde podes usar funcionalidades sem uma instância. Como os componentes de classe têm instâncias, tens mais 2 opções. Podes usar o contexto bruto diretamente ou podes usar o withMsal componente de ordem superior para injetar o contexto nos props do teu componente.

Aceder ao contexto bruto

O excerto seguinte mostra como usar o MsalContext para aceder ao contexto bruto num componente de classe.

import React from "react";
import { MsalProvider, MsalContext } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);

class App extends React.Component {
    render() {
        return (
            <MsalProvider instance={pca}>
                <YourClassComponent/>
            </ MsalProvider>
        );
    }
}

class YourClassComponent extends React.Component {
    static contextType = MsalContext;

    render() {
        const isAuthenticated = this.context.accounts.length > 0;
        if (isAuthenticated) {
            return <span>There are currently {this.context.accounts.length} users signed in!</span>
        }
    }
}

Para um exemplo funcional, consulte ProfileRawContext.jsx no nosso react-router-sample.

Aceder através de withMsal HOC

A alternativa é usar o componente de ordem superior withMsal para injetar o contexto nas propriedades do componente. O excerto seguinte mostra como usar o withMsal HOC para aceder ao contexto MSAL React num componente de classe.

import React from "react";
import { MsalProvider, withMsal } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);

class YourClassComponent extends React.Component {
    render() {
        const isAuthenticated = this.props.msalContext.accounts.length > 0;
        if (isAuthenticated) {
            return <span>There are currently {this.props.msalContext.accounts.length} users signed in!</span>
        }
    }
}

const YourWrappedComponent = withMsal(YourClassComponent);

class App extends React.Component {
    render() {
        return (
            <MsalProvider instance={pca}>
                <YourWrappedComponent />
            </ MsalProvider>
        );
    }
}

Para um exemplo funcional, consulte ProfileWithMsal.jsx em react-router-sample.

Iniciar sessão usando um componente de classe

Independentemente da abordagem que adotes para perceber o MSAL React contexto, a utilização será a mesma. Depois de teres o objeto de contexto, podes invocar qualquer uma das APIsPublicClientApplication, inspecionar as contas iniciadas ou determinar se a autenticação está em curso.

Os exemplos seguintes mostrarão como iniciar sessão usando a withMsal abordagem HOC, mas pode adaptar-se rapidamente à outra abordagem, se necessário.

Note

É importante lembrar que um MsalProvider componente deve ser renderizado a qualquer nível acima de qualquer componente que utilize contexto. Os exemplos seguintes assumem que existe um prestador e não vão demonstrar isso.

Iniciar sessão como resultado de clicar num botão

O snippet seguinte define um componente LoginButton de classe React que utiliza o withMsal componente de ordem superior. Exibe um botão que ou dispara um pop-up de login se o utilizador não estiver autenticado, ou faz logout do utilizador se estiver autenticado.

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

Iniciar sessão durante o carregamento da página

O snippet seguinte define um componente ProtectedComponent de classe React que utiliza o withMsal componente de ordem superior. Tenta autenticar o utilizador ao montar e atualizar, e mostra se o utilizador está autenticado ou se a autenticação está em curso na página de carregamento.

import React from "react";
import { withMsal } from "@azure/msal-react";
import { InteractionStatus } from "@azure/msal-browser";

class ProtectedComponent extends React.Component {
    callLogin() {
        const isAuthenticated = this.props.msalContext.accounts.length > 0;
        const msalInstance = this.props.msalContext.instance;

        // If a user is not logged in and authentication is not already in progress, invoke login
        if (!isAuthenticated && this.props.msalContext.inProgress === InteractionStatus.None) {
            msalInstance.loginPopup();
        }
    }
    componentDidMount() {
        this.callLogin();
    }

    componentDidUpdate() {
        this.callLogin();
    }
    
    render() {
        const isAuthenticated = this.props.msalContext.accounts.length > 0;
        if (isAuthenticated) {
            return <span>User is authenticated</span>
        } else {
            return <span>Authentication in progress</span>;
        }
    }
}

export default YourWrappedComponent = withMsal(ProtectedComponent);

Consulte também