> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Décrit comment utiliser votre serveur backend pour authentifier une application monopage (SPA) avec des cookies.

# Authentifier des applications monopage avec des cookies

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

export const codeExample = `ISSUER_BASE_URL="{yourDomain}"
CLIENT_ID="{yourClientId}"
BASE_URL="http://localhost:3000"
APP_SESSION_SECRET="<YOUR SECRET VALUE>"`;

La sécurisation d'une application monopage (SPA) peut représenter un défi. Toutefois, si votre SPA répond aux critères suivants, vous pouvez simplifier votre implémentation en utilisant des cookies pour l'authentification.

* Servie au client par votre propre backend.
* A le même domaine que votre backend.
* Effectue des appels d'API à votre backend qui nécessitent une authentification.

Voici une description de cette approche ainsi qu'un exemple d'implémentation avec [Node.js](https://nodejs.org/en/).

<div id="how-it-works">
  ## Fonctionnement
</div>

Les étapes ci-dessous montrent comment les jetons sont récupérés et utilisés. Dans cette approche, le [Implicit Flow with Form Post](/fr-CA/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post) est utilisé au lieu d’un [Authorization Code Flow with Proof Key for Code Exchange](/fr-CA/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) traditionnel. Cela s’explique par le fait que le mode de réponse Form Post constitue un moyen plus simple de mettre en œuvre la connexion lorsque vous demandez l’accès à votre propre ressource.

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7suPpG6SuHuCOFHeFmE21T/1bf0a56fd21f65460cff7fd01b4c93f4/2023-09-22_13-21-34.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=fbf81643a02408d39a41f7cb09db539c" alt="Schéma Authentifier des applications monopages à l’aide de cookies : fonctionnement, partie 1" width="430" height="379" data-path="docs/images/cdy7uua7fh8z/7suPpG6SuHuCOFHeFmE21T/1bf0a56fd21f65460cff7fd01b4c93f4/2023-09-22_13-21-34.png" />
</Frame>

1. L’utilisateur accède à une route protégée dans le navigateur, ou effectue une action qui exige le déclenchement d’une étape d’authentification (comme cliquer sur un bouton de connexion)
2. Le client dans le navigateur redirige vers une route `/login` sur le backend, ou vers la route protégée, selon l’action effectuée par l’utilisateur
3. Le backend construit une requête vers le point de terminaison `/authorize` du serveur d’autorisation et y redirige le navigateur
4. L’utilisateur est invité à s’authentifier à l’aide de la méthode présentée par le serveur d’autorisation
5. Le serveur d’autorisation envoie les jetons par POST à l’URI de redirection sous la forme d’un formulaire encodé dans l’URL. Le backend peut récupérer ces jetons en analysant les données du corps de la requête.

À ce stade, l’utilisateur est authentifié et le backend dispose des jetons requis. Un cookie peut maintenant être créé pour représenter cet état côté client. Le navigateur est ensuite redirigé vers une route qui sert l’application monopage et reçoit aussi le cookie d’authentification.

Par la suite, ce cookie est échangé entre le client et le backend lorsque des appels d’API sont effectués au moyen d’un appel AJAX. À chaque requête, le backend vérifie si le cookie est toujours valide et, le cas échéant, permet à la requête de se poursuivre.

<Frame>
  <img src="https://mintcdn.com/translations/6GE5Z24GDCZehiJ9/docs/images/cdy7uua7fh8z/6SCp9KwQkwJV7L26TOuxIO/d625575a43d00a00fcf17c7310ac2bc8/2023-09-22_13-21-50.png?fit=max&auto=format&n=6GE5Z24GDCZehiJ9&q=85&s=b88900ca48b64d047b7d46237dc0cf2d" alt="Schéma Authentifier des applications monopages à l’aide de cookies : fonctionnement, partie 2" width="747" height="346" data-path="docs/images/cdy7uua7fh8z/6SCp9KwQkwJV7L26TOuxIO/d625575a43d00a00fcf17c7310ac2bc8/2023-09-22_13-21-50.png" />
</Frame>

<div id="invalid-or-missing-cookies">
  ### Cookies invalides ou manquants
</div>

Lorsque vous mettez en œuvre cette approche, vous devez gérer les cas où le cookie d’authentification est invalide ou manquant. L’appel d’API au backend depuis l’application s’effectue en arrière-plan; l’application doit donc gérer toute réponse du serveur indiquant que l’utilisateur doit se réauthentifier.

Dans l’exemple d’application suivant, ce cas est géré de façon naïve en invitant l’utilisateur à se réauthentifier si l’appel d’API entraîne une redirection 302. Le code 302 se produit parce que, lorsque la validation du cookie échoue, le serveur tente de rediriger vers le point de terminaison d’autorisation du <Tooltip tip="Serveur d’autorisation : serveur centralisé qui contribue à définir les limites de l’accès d’un utilisateur. Par exemple, votre serveur d’autorisation peut contrôler les données, les tâches et les fonctionnalités accessibles à un utilisateur." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=authorization+server">serveur d’autorisation</Tooltip> et envoie cette réponse à l’application.

<div id="example">
  ## Exemple
</div>

L’application d’exemple utilise Node.js et Express pour illustrer les concepts présentés ci-dessus.

<div id="prerequisites">
  ### Prérequis
</div>

* Pour suivre ce tutoriel, assurez-vous d’avoir installé la [dernière version de Node](https://nodejs.org/en/download/).
* Une fois Node installé, [téléchargez ou clonez le code source](https://github.com/auth0-blog/spa-cookie-demo/) et ouvrez le dossier du projet dans une fenêtre de terminal.

  ```bash lines theme={null}
  # Clonez le dépôt du tutoriel à l’aide de SSH
  git clone git@github.com:auth0-blog/spa-cookie-demo
  # ... ou si vous utilisez HTTPS :
  git clone https://github.com/auth0-blog/spa-cookie-demo.git
  # Accédez au répertoire du projet
  cd spa-cookie-demo
  ```
* La branche `master` représente l’état de l’application avant l’ajout de toute authentification. Si vous voulez consulter la version finale de l’application, basculez vers la branche `with-oidc` :
  `git checkout with-oidc`

<div id="initialize-the-nodejs-app">
  ### Initialiser l’application Node.js
</div>

Installez les dépendances de l’application en exécutant `npm install` dans votre terminal. Pour lancer l’application, utilisez `npm run dev`. Cette commande démarre le serveur Express. Ouvrez [http://localhost:3000](http://localhost:3000/) dans votre navigateur pour afficher l’application.

Le serveur de développement utilise `nodemon`, qui redémarre automatiquement dès qu’il détecte des modifications de fichiers.

<div id="explore-the-application">
  ### Explorez l’application
</div>

Avec l’application ouverte à l’adresse [http://localhost:3000](http://localhost:3000/), cliquez sur le bouton **Call API**. Un message devrait s’afficher à l’écran.

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7JhdgzFLig2xcDle7ziiGp/c1db6272d20d4a291ba90a6968460109/image3.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=162359e67c515f737bfb5bcee4676480" alt="Écran « Explore the application » de l’authentification SPA avec cookies" width="937" height="677" data-path="docs/images/cdy7uua7fh8z/7JhdgzFLig2xcDle7ziiGp/c1db6272d20d4a291ba90a6968460109/image3.png" />
</Frame>

Notez que vous avez pu effectuer l’appel à l’API sans être connecté. Corrigeons cela en ajoutant un middleware qui exige que l’utilisateur s’authentifie avant de pouvoir effectuer l’appel à l’API.

<div id="set-up-environment">
  ### Configurer l’environnement
</div>

Pour que l’application fonctionne avec l’authentification, `express-openid-connect` nécessite la présence de certaines variables d’environnement. Pour cette application, ces variables peuvent être définies dans un fichier `.env`. Créez un fichier `.env` à la racine du répertoire du projet et ajoutez-y ce qui suit :

```shell .env lines theme={null}
ISSUER_BASE_URL="<YOUR OIDC URL>"
CLIENT_ID="<YOUR OIDC CLIENT ID>"
BASE_URL="http://localhost:3000"
APP_SESSION_SECRET="<YOUR SECRET VALUE>"
```

<div id="set-up-app-in-auth0">
  ### Configurer l’application dans Auth0
</div>

1. Accédez à [Auth0 Dashboard > Applications > Applications](https://manage.auth0.com/#/applications), puis cliquez sur **Create Application**.
2. Donnez un nom à votre nouvelle application, sélectionnez **Regular Web Applications**, puis cliquez sur **Create**
3. Dans les **Settings** de votre nouvelle application, ajoutez `http:/localhost:3000/callback` à **Allowed Callback URLs**.
4. Ajoutez `http:/localhost:3000` à **Allowed Logout URLs**.
5. Cliquez sur **Save Changes**.
6. Accédez à [Auth0 Dashboard > Authentication > Social](https://manage.auth0.com/#/connections/social) et configurez quelques connexions sociales. Activez-les pour votre application dans les options **Application** de l’onglet **Connections**. Cet exemple utilise une base de données avec nom d’utilisateur et mot de passe, Facebook, Google et X.
7. Dans l’écran **Settings**, notez les paramètres de Domaine et d’ID client affichés en haut.
8. Deux valeurs doivent être configurées dans l’application. Rouvrez le fichier `.env` et définissez ces valeurs :

   <AuthCodeBlock children={codeExample} language="shell" filename=".env" />

<div id="run-the-app">
  ### Exécutez l’application
</div>

1. Une fois la configuration du serveur et de l’environnement terminée, repérez la fenêtre de navigateur où l’application est ouverte. Si vous avez fermé le navigateur et arrêté le serveur, exécutez la commande suivante dans le terminal pour redémarrer l’application :
   `npm run dev`
2. Ouvrez `http://localhost:3000` dans le navigateur. Du point de vue de l’interface utilisateur, l’application devrait avoir la même apparence. Toutefois, cette fois-ci, lorsque vous cliquez sur le bouton **Call API**, vous devriez voir un avertissement indiquant que l’utilisateur n’est pas connecté. Notez aussi que vous ne voyez pas le message "Hello, World" comme auparavant, puisque l’appel à l’API a été rejeté.
3. Cliquez sur **Log in now** pour vous connecter. Une fois authentifié, vous retournerez à l’application et verrez une interface mise à jour qui reflète votre nouvel état de connexion. Vous devriez pouvoir cliquer de nouveau sur le bouton **Call API** pour lancer un appel à l’API vers le serveur, et cette fois, il fonctionnera.
4. Cliquez sur le lien **Profile** en haut de la page pour afficher les informations de l’utilisateur récupérées à partir de l’ID Token.

<div id="learn-more">
  ## En savoir plus
</div>

* [Flux implicite avec envoi par formulaire](/fr-CA/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post)
* [Sécurité](/fr-CA/docs/secure)
* [Modifications apportées à l’attribut de cookie SameSite](/fr-CA/docs/manage-users/cookies/samesite-cookie-attribute-changes)
