Partager via


Application monopage (SPA) : acquérir un jeton pour appeler une API

S’applique à : cercle vert avec un symbole de coche blanc qui indique que le contenu suivant s’applique aux locataires du personnel. Locataires de main-d’œuvre (en savoir plus)

Le modèle permettant d'acquérir des jetons pour les API avec MSAL.js consiste d'abord à tenter une demande de jeton en mode silencieux à l'aide de la méthode acquireTokenSilent. Lorsque cette méthode est appelée, la bibliothèque vérifie d’abord le cache dans le stockage du navigateur pour voir s’il existe un jeton d’accès non expiré, et le retourne. Si aucun jeton d’accès n’est trouvé ou si le jeton d’accès trouvé a expiré, elle tente d’utiliser son jeton d’actualisation pour obtenir un nouveau jeton d’accès. Si la durée de vie de 24 heures du jeton d'actualisation a également expiré, MSAL.js ouvre une iframe masquée pour demander silencieusement un nouveau code d'autorisation en utilisant la session active existante avec l'ID Microsoft Entra (le cas échéant), qui sera ensuite échangé contre un nouvel ensemble. de jetons (jetons d’accès et de rafraîchissement).

Pour plus d'informations sur les valeurs de session d'authentification unique (SSO) et de durée de vie des jetons dans Microsoft Entra ID, consultez Durées de vie des jetons. Pour plus d’informations sur la stratégie de recherche de cache MSAL.js, consultez : Acquisition d’un jeton d’accès.

Les demandes de jetons silencieux adressées à Microsoft Entra ID peuvent échouer pour des raisons telles qu'un changement de mot de passe ou des stratégies d'accès conditionnel mises à jour. Le plus souvent, les échecs sont dus à l'expiration de la durée de vie de 24 heures du jeton d'actualisation et au blocage des cookies de tiers par le navigateur, ce qui empêche l'utilisation des iframes masqués pour poursuivre l'authentification de l'utilisateur. Dans ces cas, vous devez appeler l'une des méthodes interactives (qui peut envoyer une invite à l'utilisateur) pour acquérir des jetons :

Choisir entre une expérience avec pop-up ou une redirection

Le choix entre la fenêtre contextuelle et la redirection dépend du flux de votre application :

  • Si vous ne souhaitez pas que les utilisateurs quittent la page principale de votre application lors de l’authentification, nous vous recommandons d’utiliser la méthode avec fenêtre contextuelle. La redirection de l’authentification se produisant dans une fenêtre contextuelle, l’état de l’application principale est conservé.
  • Si les utilisateurs sont soumis à des contraintes imposées par le navigateur ou par des stratégies qui bloquent les fenêtres contextuelles, vous pouvez utiliser la méthode avec redirection. Utilisez la méthode avec redirection dans le navigateur Internet Explorer, car il existe des problèmes connus avec l’utilisation de fenêtres contextuelles dans Internet Explorer.

Vous pouvez définir les étendues d’API qui doivent être incluses dans le jeton d’accès lors de la création de la requête de jeton d’accès. Toutes les étendues demandées sont susceptibles de ne pas être toutes accordées dans le jeton d’accès. Cela dépend du consentement de l’utilisateur.

Acquérir un jeton avec une fenêtre contextuelle

Le code suivant combine le modèle décrit précédemment aux méthodes offrant une expérience de fenêtre contextuelle :

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

Par ailleurs, si vous devez acquérir un jeton en dehors d'un composant React, vous pouvez appeler acquireTokenSilent mais vous ne devez pas revenir à l'interaction en cas d'échec. Toutes les interactions doivent avoir lieu sous le composant MsalProvider dans l’arborescence des composants.

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

Acquérir un jeton avec une redirection

En cas d'échec d'acquireTokenSilent, revenez à acquireTokenRedirect. Cette méthode lance une redirection complète et la réponse est gérée lors du retour à l’application. Lors de l'affichage de ce composant après le retour de la redirection, acquireTokenSilent doit être correctement exécuté, car les jetons seront extraits du 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>
  );
}

Par ailleurs, si vous devez acquérir un jeton en dehors d'un composant React, vous pouvez appeler acquireTokenSilent mais vous ne devez pas revenir à l'interaction en cas d'échec. Toutes les interactions doivent avoir lieu sous le composant MsalProvider dans l’arborescence des composants.

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

Étape suivante