Partilhar via


Aplicativo de página única: adquira um token para chamar uma API

Aplica-se a: Círculo verde com um símbolo de marca de verificação branco. Locatários de trabalho Círculo branco com um símbolo X cinzento. Locatários externos (saiba mais)

O padrão para adquirir tokens para APIs com MSAL.js é primeiro tentar uma solicitação de token silenciosa usando o acquireTokenSilent método. Quando esse método é chamado, a biblioteca primeiro verifica o cache no armazenamento do navegador para ver se existe um token de acesso não expirado e o retorna. Se nenhum token de acesso for encontrado ou se o token de acesso encontrado tiver expirado, ele tentará usar seu token de atualização para obter um novo token de acesso. Se o tempo de vida de 24 horas do token de atualização também tiver expirado, MSAL.js abre um iframe oculto para solicitar silenciosamente um novo código de autorização usando a sessão ativa existente com o Microsoft Entra ID (se houver), que será trocado por um novo conjunto de tokens (tokens de acesso e atualização).

Para obter mais informações sobre a sessão de logon único (SSO) e os valores do tempo de vida do token no ID do Microsoft Entra, consulte Tempos de vida do token. Para obter mais informações sobre MSAL.js política de pesquisa de cache, consulte: Adquirindo um token de acesso.

As solicitações de token silencioso para o Microsoft Entra ID podem falhar por motivos como uma alteração de senha ou políticas de Acesso Condicional atualizadas. Na maioria das vezes, as falhas são devido à vida útil de 24 horas do token de atualização expirando e o navegador bloqueando cookies de terceiros, o que impede o uso de iframes ocultos para continuar autenticando o usuário. Nesses casos, você deve invocar um dos métodos interativos (que podem solicitar ao usuário) para adquirir tokens:

Escolha entre uma experiência pop-up ou de redirecionamento

A escolha entre uma experiência pop-up ou de redirecionamento depende do fluxo do seu aplicativo:

  • Se você não quiser que os usuários se afastem da página principal do aplicativo durante a autenticação, recomendamos o método pop-up. Como o redirecionamento de autenticação acontece em uma janela pop-up, o estado do aplicativo principal é preservado.
  • Se os usuários tiverem restrições de navegador ou políticas em que as janelas pop-up estejam desativadas, você poderá usar o método de redirecionamento. Use o método de redirecionamento com o navegador Internet Explorer, porque há problemas conhecidos com janelas pop-up no Internet Explorer.

Você pode definir os escopos de API que deseja que o token de acesso inclua quando estiver criando a solicitação de token de acesso. Todos os escopos solicitados podem não ser concedidos no token de acesso. Isso depende do consentimento do usuário.

Obtenha um token com uma janela pop-up

O código a seguir combina o padrão descrito anteriormente com os métodos para uma experiência pop-up:

import {
  InteractionRequiredAuthError,
  InteractionStatus,
} from "@azure/msal-browser";
import { AuthenticatedTemplate, useMsal } from "@azure/msal-react";

function ProtectedComponent() {
  const { instance, inProgress, accounts } = useMsal();
  const [apiData, setApiData] = useState(null);

  useEffect(() => {
    if (!apiData && inProgress === InteractionStatus.None) {
      const accessTokenRequest = {
        scopes: ["user.read"],
        account: accounts[0],
      };
      instance
        .acquireTokenSilent(accessTokenRequest)
        .then((accessTokenResponse) => {
          // Acquire token silent success
          let accessToken = accessTokenResponse.accessToken;
          // Call your API with token
          callApi(accessToken).then((response) => {
            setApiData(response);
          });
        })
        .catch((error) => {
          if (error instanceof InteractionRequiredAuthError) {
            instance
              .acquireTokenPopup(accessTokenRequest)
              .then(function (accessTokenResponse) {
                // Acquire token interactive success
                let accessToken = accessTokenResponse.accessToken;
                // Call your API with token
                callApi(accessToken).then((response) => {
                  setApiData(response);
                });
              })
              .catch(function (error) {
                // Acquire token interactive failure
                console.log(error);
              });
          }
          console.log(error);
        });
    }
  }, [instance, accounts, inProgress, apiData]);

  return <p>Return your protected content here: {apiData}</p>;
}

function App() {
  return (
    <AuthenticatedTemplate>
      <ProtectedComponent />
    </AuthenticatedTemplate>
  );
}

Como alternativa, se precisar adquirir um token fora de um componente React, pode chamar acquireTokenSilent, mas não deve recorrer à interação se isso falhar. Todas as interações devem ocorrer abaixo do MsalProvider componente na árvore de componentes.

// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];

const accessTokenRequest = {
  scopes: ["user.read"],
  account: account,
};

// Use the same publicClientApplication instance provided to MsalProvider
publicClientApplication
  .acquireTokenSilent(accessTokenRequest)
  .then(function (accessTokenResponse) {
    // Acquire token silent success
    let accessToken = accessTokenResponse.accessToken;
    // Call your API with token
    callApi(accessToken);
  })
  .catch(function (error) {
    //Acquire token silent failure
    console.log(error);
  });

Obtenha um token com um redirecionamento

Se acquireTokenSilent falhar, alternar para acquireTokenRedirect. Esse método inicia um redirecionamento de quadro completo e a resposta será tratada ao retornar ao aplicativo. Quando esse componente é renderizado depois de retornar do redirecionamento, acquireTokenSilent deve agora ter êxito, pois os tokens serão retirados do cache.

import {
  InteractionRequiredAuthError,
  InteractionStatus,
} from "@azure/msal-browser";
import { AuthenticatedTemplate, useMsal } from "@azure/msal-react";

function ProtectedComponent() {
  const { instance, inProgress, accounts } = useMsal();
  const [apiData, setApiData] = useState(null);

  useEffect(() => {
    const accessTokenRequest = {
      scopes: ["user.read"],
      account: accounts[0],
    };
    if (!apiData && inProgress === InteractionStatus.None) {
      instance
        .acquireTokenSilent(accessTokenRequest)
        .then((accessTokenResponse) => {
          // Acquire token silent success
          let accessToken = accessTokenResponse.accessToken;
          // Call your API with token
          callApi(accessToken).then((response) => {
            setApiData(response);
          });
        })
        .catch((error) => {
          if (error instanceof InteractionRequiredAuthError) {
            instance.acquireTokenRedirect(accessTokenRequest);
          }
          console.log(error);
        });
    }
  }, [instance, accounts, inProgress, apiData]);

  return <p>Return your protected content here: {apiData}</p>;
}

function App() {
  return (
    <AuthenticatedTemplate>
      <ProtectedComponent />
    </AuthenticatedTemplate>
  );
}

Como alternativa, se precisar adquirir um token fora de um componente React, pode chamar acquireTokenSilent, mas não deve recorrer à interação se isso falhar. Todas as interações devem ocorrer abaixo do MsalProvider componente na árvore de componentes.

// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];

const accessTokenRequest = {
  scopes: ["user.read"],
  account: account,
};

// Use the same publicClientApplication instance provided to MsalProvider
publicClientApplication
  .acquireTokenSilent(accessTokenRequest)
  .then(function (accessTokenResponse) {
    // Acquire token silent success
    let accessToken = accessTokenResponse.accessToken;
    // Call your API with token
    callApi(accessToken);
  })
  .catch(function (error) {
    //Acquire token silent failure
    console.log(error);
  });

Próximo passo