> ## 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.

# Protégez votre API Express.js

> Ce guide explique comment protéger les points de terminaison d’une API Express.js à l’aide de jetons d’accès JWT avec le SDK express-oauth2-jwt-bearer.

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Callout icon="pencil" color="#FFC107" iconType="solid">
  Une nouvelle version **Beta** de ce Quickstart est maintenant offerte avec le SDK `@auth0/auth0-express-api`, qui remplacera bientôt ce guide. [Essayer le Quickstart Beta →](/docs/fr-ca/quickstart/backend/express-api-beta)
</Callout>

<Accordion title="Utiliser l’IA pour intégrer Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si vous utilisez un assistant de codage IA comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification de l’API Auth0 en quelques minutes à l’aide d’[Agent Skills](https://agentskills.io/home).

  **Installer :**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0
  ```

  **Ensuite, demandez à votre assistant IA :**

  ```text theme={null}
  Add Auth0 JWT authentication to my Express API
  ```

  Votre assistant IA créera automatiquement votre API Auth0, récupérera les identifiants, installera `express-oauth2-jwt-bearer`, configurera le middleware JWT et protégera vos points de terminaison d’API grâce à la validation des tokens. [Documentation complète sur Agent Skills →](/docs/fr-ca/quickstart/agent-skills)
</Accordion>

<Note>
  **Prérequis :** Avant de commencer, assurez-vous d’avoir installé ce qui suit :

  * **[Node.js](https://nodejs.org/en/download)** 18 LTS ou une version ultérieure (prend en charge `^18.12.0 || ^20.2.0 || ^22.1.0 || ^24.0.0`)
  * **[npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)** 8+ ou **[yarn](https://classic.yarnpkg.com/lang/en/docs/install/)** 1.22+ ou **[pnpm](https://pnpm.io/installation)** 8+

  Vérifiez l’installation : `node --version && npm --version`

  **Compatibilité des versions d’Express :** Ce Quickstart fonctionne avec **Express 4.x** et **Express 5.x**.
</Note>

<div id="get-started">
  ## Pour commencer
</div>

Ce Quickstart montre comment protéger des points de terminaison d’API Express.js à l’aide de jetons d’accès JWT. Vous allez créer une API sécurisée qui valide les jetons d’accès Auth0, protège des routes et met en œuvre une autorisation basée sur les scopes.

<Steps>
  <Step title="Créer un nouveau projet" stepNumber={1}>
    Créez un nouveau répertoire pour votre API Express, puis initialisez un projet Node.js.

    ```shellscript theme={null}
    mkdir auth0-express-api && cd auth0-express-api
    ```

    Initialiser le projet

    ```shellscript theme={null}
    npm init -y
    ```

    Créer la structure du projet

    ```shellscript theme={null}
    touch server.js .env
    ```
  </Step>

  <Step title="Installer le SDK express-oauth2-jwt-bearer" stepNumber={2}>
    Installez les dépendances nécessaires

    ```shellscript theme={null}
    npm install express express-oauth2-jwt-bearer dotenv
    ```

    Ajoutez des scripts `start` à votre `package.json` :

    ```json package.json theme={null}
    {
      "scripts": {
        "start": "node server.js",
        "dev": "node --watch server.js"
      }
    }
    ```
  </Step>

  <Step title="Configurez votre API Auth0" stepNumber={3}>
    Ensuite, vous devez créer une nouvelle API dans votre tenant Auth0 et ajouter les variables d’environnement à votre projet.

    Vous avez deux options pour configurer votre API Auth0 : utiliser une commande CLI ou passer par le Dashboard manuellement :

    <Tabs>
      <Tab title="CLI">
        Exécutez la commande suivante à la racine de votre projet pour créer une API Auth0 :

        <CodeGroup>
          ```shellscript Mac theme={null}
          # Installer Auth0 CLI (si ce n’est pas déjà fait)
          brew tap auth0/auth0-cli && brew install auth0

          # Créer une API Auth0
          auth0 apis create \
            --name "My Express API" \
            --identifier https://my-express-api.example.com
          ```

          ```powershell Windows theme={null}
          # Installer Auth0 CLI (si ce n’est pas déjà fait)
          scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
          scoop install auth0

          # Créer une API Auth0
          auth0 apis create `
            --name "My Express API" `
            --identifier https://my-express-api.example.com
          ```
        </CodeGroup>

        <Note>
          Cette commande va :

          1. Vérifier si vous êtes authentifié (et vous inviter à vous connecter au besoin)
          2. Créer une API Auth0 avec l’identifiant indiqué
          3. Afficher les détails de l’API, y compris le domaine et l’identifiant
        </Note>

        Une fois l’API créée, copiez les valeurs **Identifier** et **Domain**, puis créez votre fichier `.env` :

        ```bash .env theme={null}
        AUTH0_DOMAIN=YOUR_AUTH0_DOMAIN
        AUTH0_AUDIENCE=YOUR_API_IDENTIFIER
        ```

        <Note>
          Remplacez `YOUR_AUTH0_DOMAIN` par le domaine de votre tenant Auth0 (par exemple, `dev-abc123.us.auth0.com`) et `YOUR_API_IDENTIFIER` par l’identifiant de votre API (par exemple, `https://my-express-api.example.com`).
        </Note>
      </Tab>

      <Tab title="Dashboard">
        1. Accédez au [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Allez à **Applications** → **APIs** → **Create API**
        3. Saisissez un nom pour votre API (par exemple, "My Express API")
        4. Définissez l’**Identifier** (par exemple, `https://my-express-api.example.com`)
           * Il s’agit de l’audience de votre API et elle doit respecter un format d’URL valide
           * Il n’est pas nécessaire qu’il s’agisse d’une vraie URL : c’est simplement un identifiant
        5. Laissez **Signing Algorithm** à **RS256**
        6. Cliquez sur **Create**
        7. Copiez la valeur **Identifier** depuis l’onglet **Settings**

        Créez votre fichier `.env` avec les valeurs suivantes :

        ```bash .env theme={null}
        AUTH0_DOMAIN=YOUR_AUTH0_DOMAIN
        AUTH0_AUDIENCE=YOUR_API_IDENTIFIER
        ```

        <Note>
          Remplacez `YOUR_AUTH0_DOMAIN` par le domaine de votre tenant Auth0 (par exemple, `dev-abc123.us.auth0.com`) et `YOUR_API_IDENTIFIER` par l’identifiant de votre API dans le dashboard (par exemple, `https://my-express-api.example.com`).
        </Note>
      </Tab>
    </Tabs>

    <Tip>
      Vérifiez que votre fichier `.env` existe : `cat .env` (Mac/Linux) ou `type .env` (Windows)
    </Tip>
  </Step>

  <Step title="Configurer le middleware JWT" stepNumber={4}>
    Créez votre serveur Express et configurez la validation JWT :

    ```javascript server.js {1-3,6-7,10-13} lines theme={null}
    require('dotenv').config();
    const express = require('express');
    const { auth } = require('express-oauth2-jwt-bearer');

    const app = express();
    const port = process.env.PORT || 3001;

    // Configurer le middleware de validation JWT
    const checkJwt = auth({
      issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
      audience: process.env.AUTH0_AUDIENCE,
    });

    // Démarrer le serveur
    app.listen(port, () => {
      console.log(`API server running at http://localhost:${port}`);
    });
    ```

    **Ce que cela fait :**

    * Crée un middleware de validation JWT à l’aide de votre domaine Auth0 et de l’audience de l’API
    * Valide les claims `iss` et `aud` des jetons d’accès reçus
    * Met `checkJwt` à disposition pour protéger des routes précises
  </Step>

  <Step title="Créer des routes d’API" stepNumber={5}>
    Ajoutez des routes publiques et protégées à votre `server.js` :

    ```javascript server.js expandable lines theme={null}
    require('dotenv').config();
    const express = require('express');
    const { auth, requiredScopes } = require('express-oauth2-jwt-bearer');

    const app = express();
    const port = process.env.PORT || 3001;

    // Configurer le middleware de validation JWT
    const checkJwt = auth({
      issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
      audience: process.env.AUTH0_AUDIENCE,
    });

    // Route publique - aucune authentification requise
    app.get('/api/public', (req, res) => {
      res.json({
        message: 'Hello from a public endpoint! You don\'t need to be authenticated to see this.',
        timestamp: new Date().toISOString(),
      });
    });

    // Route protégée - nécessite un access token valide
    app.get('/api/private', checkJwt, (req, res) => {
      res.json({
        message: 'Hello from a protected endpoint! You successfully authenticated.',
        user: req.auth.payload.sub,
        timestamp: new Date().toISOString(),
      });
    });

    // Route protégée avec scope - nécessite le scope 'read:messages'
    app.get('/api/private-scoped', checkJwt, requiredScopes('read:messages'), (req, res) => {
      res.json({
        message: 'Hello from a scoped endpoint! You have the required permission.',
        user: req.auth.payload.sub,
        scope: req.auth.payload.scope,
        timestamp: new Date().toISOString(),
      });
    });

    // Middleware de gestion des erreurs
    app.use((err, req, res, next) => {
      const status = err.status || 500;
      const message = err.message || 'Internal Server Error';

      res.status(status).json({
        error: err.code || 'server_error',
        message: status === 401 ? 'Authentication required' : message,
      });
    });

    // Démarrer le serveur
    app.listen(port, () => {
      console.log(`API server running at http://localhost:${port}`);
    });
    ```

    **Points clés :**

    * Les routes publiques ne nécessitent pas d'authentification
    * Les routes protégées utilisent le middleware `checkJwt` pour exiger un JWT valide
    * Les routes avec scopes utilisent `requiredScopes()` pour exiger des permissions précises dans le token
    * `req.auth.payload` contient les claims JWT décodés pour les requêtes authentifiées
    * Le claim `sub` contient l'identifiant unique de l'utilisateur
  </Step>

  <Step title="Lancez votre API" stepNumber={6}>
    Démarrez le serveur de développement :

    ```shellscript theme={null}
    npm run dev
    ```

    Votre API est maintenant accessible à l’adresse [http://localhost:3001](http://localhost:3001).

    <Info>
      L’option `--watch` de Node.js 18+ redémarre automatiquement le serveur lorsque des fichiers sont modifiés.
    </Info>
  </Step>

  <Step title="Testez votre API" stepNumber={7}>
    Testez le point de terminaison public (aucune authentification requise) :

    ```bash theme={null}
    curl http://localhost:3001/api/public
    ```

    Vous devriez voir :

    ```json theme={null}
    {
      "message": "Hello from a public endpoint! You don't need to be authenticated to see this.",
      "timestamp": "2024-01-15T10:30:00.000Z"
    }
    ```

    Testez l’endpoint protégé sans token (cela devrait échouer) :

    ```bash theme={null}
    curl http://localhost:3001/api/private
    ```

    Vous devriez voir une erreur 401 Unauthorized :

    ```json theme={null}
    {
      "error": "unauthorized",
      "message": "Authentication required"
    }
    ```

    Pour tester avec un jeton valide :

    1. Accédez à [Auth0 Dashboard](https://manage.auth0.com/) → **Applications** → **APIs**
    2. Sélectionnez votre API → onglet **Test**
    3. Copiez le jeton d’accès généré

    Testez votre point de terminaison protégé :

    ```bash theme={null}
    curl http://localhost:3001/api/private \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
    ```

    Vous devriez voir :

    ```json theme={null}
    {
      "message": "Hello from a protected endpoint! You successfully authenticated.",
      "user": "auth0|abc123...",
      "timestamp": "2024-01-15T10:30:00.000Z"
    }
    ```
  </Step>
</Steps>

<Check>
  **Vérification**

  Vous devriez maintenant avoir une API protégée. Votre API :

  1. Accepte les requêtes vers des points de terminaison publics sans authentification
  2. Rejette les requêtes vers des points de terminaison protégés sans jeton valide
  3. Valide les jetons JWT à l’aide de votre domaine Auth0 et de l’audience
  4. Fournit des renseignements sur l’utilisateur à partir des claims du jeton au moyen de `req.auth.payload`
</Check>

***

<div id="advanced-usage">
  ## Utilisation avancée
</div>

<Accordion title="Autorisation basée sur les scopes">
  Les scopes permettent un contrôle d’accès granulaire. Vous pouvez exiger des scopes précis pour différents points de terminaison.

  **Configurer les scopes dans Auth0 :**

  1. Dans le [Auth0 Dashboard](https://manage.auth0.com/), accédez à **Applications** → **APIs** → votre API
  2. Accédez à l’onglet **Permissions**
  3. Ajoutez des permissions comme `read:messages`, `write:messages`, `admin:access`

  **Protéger des routes avec des scopes :**

  ```javascript server.js theme={null}
  const { auth, requiredScopes } = require('express-oauth2-jwt-bearer');

  // Exige le scope 'read:messages'
  app.get('/api/messages', checkJwt, requiredScopes('read:messages'), (req, res) => {
    res.json({
      messages: [
        { id: 1, text: 'Hello!' },
        { id: 2, text: 'World!' },
      ],
    });
  });

  // Exige le scope 'admin:access'
  app.get('/api/admin', checkJwt, requiredScopes('admin:access'), (req, res) => {
    res.json({
      message: 'Admin access granted',
      userId: req.auth.payload.sub,
    });
  });
  ```

  <Note>
    Si une requête ne contient pas le scope requis, l’API renvoie `403 Forbidden` avec une erreur `insufficient_scope`. Assurez-vous que l’application cliente demande les bons scopes lors de l’obtention d’un jeton d’accès.
  </Note>
</Accordion>

<Accordion title="Validation de claims personnalisées">
  En plus des scopes, vous pouvez valider des claims personnalisées dans le payload JWT :

  ```javascript server.js theme={null}
  const { auth, claimEquals, claimIncludes, claimCheck } = require('express-oauth2-jwt-bearer');

  // Exige une valeur exacte de claim
  app.get('/api/org/:orgId',
    checkJwt,
    claimEquals('org_id', 'org_123'),
    (req, res) => {
      res.json({ message: 'Organization access granted' });
    }
  );

  // Exige que la claim inclue toutes les valeurs précisées
  app.get('/api/roles',
    checkJwt,
    claimIncludes('roles', 'editor', 'viewer'),
    (req, res) => {
      res.json({ message: 'Role check passed' });
    }
  );

  // Logique de validation de claim personnalisée
  app.get('/api/premium',
    checkJwt,
    claimCheck((claims) => {
      return claims.subscription === 'premium' && claims.verified === true;
    }),
    (req, res) => {
      res.json({ message: 'Premium feature access granted' });
    }
  );
  ```

  <Note>
    Les claims personnalisées doivent utiliser des URL avec espace de noms (p. ex., `https://myapp.com/roles`), à moins qu’il ne s’agisse de claims OIDC standard. [En savoir plus sur les claims personnalisées](https://auth0.com/docs/secure/tokens/json-web-tokens/create-custom-claims).
  </Note>
</Accordion>

<Accordion title="Authentification facultative (routes publiques/privées mixtes)">
  Permettez l’accès authentifié et anonyme à une même route :

  ```javascript server.js theme={null}
  const optionalAuth = auth({
    issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
    audience: process.env.AUTH0_AUDIENCE,
    authRequired: false,
  });

  app.get('/api/feed', optionalAuth, (req, res) => {
    if (req.auth) {
      res.json({
        message: `Welcome back, ${req.auth.payload.sub}!`,
        personalizedContent: true,
      });
    } else {
      res.json({
        message: 'Welcome, guest!',
        personalizedContent: false,
      });
    }
  });
  ```
</Accordion>

<Accordion title="Configuration CORS">
  Activez CORS pour autoriser les requêtes provenant d’applications Web :

  ```bash theme={null}
  npm install cors
  ```

  ```javascript server.js theme={null}
  const cors = require('cors');

  app.use(cors({
    origin: ['http://localhost:3000', 'http://localhost:5173'],
    allowedHeaders: ['Authorization', 'Content-Type'],
    exposedHeaders: ['WWW-Authenticate'],
  }));
  ```

  En Production, précisez les origines exactes :

  ```javascript server.js theme={null}
  app.use(cors({
    origin: [
      'https://myapp.com',
      'https://www.myapp.com'
    ],
    credentials: true,
    methods: ['GET', 'POST', 'PUT', 'DELETE'],
  }));
  ```
</Accordion>

<Accordion title="Gestion personnalisée des erreurs">
  Ajoutez une gestion complète des erreurs d’authentification :

  ```javascript server.js theme={null}
  const { UnauthorizedError, InvalidTokenError, InsufficientScopeError } = require('express-oauth2-jwt-bearer');

  app.use((err, req, res, next) => {
    if (err instanceof InsufficientScopeError) {
      return res.status(403).json({
        error: 'forbidden',
        message: 'You do not have permission to access this resource',
        required_scopes: err.requiredScopes,
      });
    }

    if (err instanceof InvalidTokenError) {
      return res.status(401).json({
        error: 'invalid_token',
        message: 'The provided token is invalid or expired',
      });
    }

    if (err instanceof UnauthorizedError) {
      return res.status(401).set(err.headers).json({
        error: 'unauthorized',
        message: 'Authentication required',
      });
    }

    next(err);
  });
  ```
</Accordion>

<Accordion title="Prise en charge de TypeScript">
  Pour les projets TypeScript, installez les définitions de types et configurez votre projet :

  ```bash theme={null}
  npm install -D typescript @types/express @types/node
  ```

  Créez `server.ts` :

  ```typescript server.ts theme={null}
  import 'dotenv/config';
  import express, { Request, Response, NextFunction } from 'express';
  import { auth, requiredScopes, UnauthorizedError } from 'express-oauth2-jwt-bearer';

  const app = express();
  const port = process.env.PORT || 3001;

  const checkJwt = auth({
    issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
    audience: process.env.AUTH0_AUDIENCE,
  });

  app.get('/api/public', (req: Request, res: Response) => {
    res.json({ message: 'Public endpoint - no authentication required' });
  });

  app.get('/api/private', checkJwt, (req: Request, res: Response) => {
    res.json({
      message: 'Private endpoint',
      user: req.auth?.payload.sub,
    });
  });

  app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
    if (err instanceof UnauthorizedError) {
      res.status(err.status).set(err.headers).json({
        error: err.code || 'unauthorized',
        message: 'Authentication required',
      });
    } else {
      res.status(500).json({
        error: 'server_error',
        message: 'Internal Server Error',
      });
    }
  });

  app.listen(port, () => {
    console.log(`API server running at http://localhost:${port}`);
  });
  ```

  Ajoutez un `tsconfig.json` :

  ```json tsconfig.json theme={null}
  {
    "compilerOptions": {
      "target": "ES2020",
      "module": "commonjs",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "outDir": "./dist"
    },
    "include": ["*.ts"]
  }
  ```

  Exécutez avec : `npx ts-node server.ts`
</Accordion>

***

<div id="troubleshooting">
  ## Dépannage
</div>

<AccordionGroup>
  <Accordion title="Problèmes courants et solutions">
    ### "Aucun jeton d'autorisation n'a été trouvé"

    **Problème :** L’API ne trouve pas le jeton d’accès dans la requête.

    **Solutions :**

    1. Assurez-vous que l’en-tête `Authorization` est présent : `Authorization: Bearer YOUR_TOKEN`
    2. Vérifiez que "Bearer" est bien indiqué avant le jeton
    3. Vérifiez que le jeton n’est pas expiré

    ### "Jeton invalide" ou "jwt malformed"

    **Problème :** Le format du jeton n’est pas valide.

    **Solutions :**

    1. Assurez-vous d’utiliser un **jeton d’accès**, et non un ID token
    2. Le jeton doit être obtenu avec le paramètre `audience` de votre API
    3. Vérifiez que le jeton est un JWT valide (il doit comporter trois parties séparées par des points)

    ### Valeur "iss" ou "aud" inattendue

    **Problème :** L’émetteur ou l’audience du jeton ne correspond pas à votre configuration.

    **Solutions :**

    1. Décodez votre jeton sur [jwt.io](https://jwt.io)
    2. Vérifiez que la claim `iss` correspond à `https://YOUR_AUTH0_DOMAIN/` (notez la barre oblique à la fin)
    3. Vérifiez que la claim `aud` correspond exactement à votre `AUTH0_AUDIENCE`
    4. Vérifiez les valeurs de votre `.env` :

    ```bash theme={null}
    AUTH0_DOMAIN=dev-abc123.us.auth0.com
    AUTH0_AUDIENCE=https://my-express-api.example.com
    ```

    ### "You must provide an issuerBaseURL" ou "audience is required"

    **Problème :** Les variables d’environnement ne sont pas chargées.

    **Solutions :**

    1. Assurez-vous que le fichier `.env` existe à la racine de votre projet
    2. Vérifiez que `dotenv` est installé : `npm install dotenv`
    3. Ajoutez `require('dotenv').config()` tout en haut de votre fichier serveur
    4. Vérifiez que les noms de variables correspondent exactement, y compris la casse

    ### 401 Unauthorized pour toutes les requêtes

    **Causes possibles :**

    * Le jeton est expiré
    * L’audience ne correspond pas
    * L’émetteur ne correspond pas

    **Étapes de débogage :**

    1. Décodez votre jeton sur [jwt.io](https://jwt.io)
    2. Vérifiez que la claim `exp` n’est pas expirée
    3. Vérifiez que la claim `aud` correspond exactement à votre `AUTH0_AUDIENCE`
    4. Vérifiez que la claim `iss` est `https://{AUTH0_DOMAIN}/`
    5. Assurez-vous que le format de l’en-tête `Authorization` est `Bearer YOUR_TOKEN` (avec un espace)

    ### 403 Forbidden avec "insufficient\_scope"

    **Problème :** Le jeton n’a pas les scopes requis.

    **Solutions :**

    1. Vérifiez que les scopes sont définis dans votre API Auth0 (Dashboard → **Applications** → **APIs** → **Permissions**)
    2. Demandez les scopes au moment d’obtenir le jeton
    3. Vérifiez que la claim `scope` du jeton inclut les scopes requis

    ### Erreurs CORS dans le navigateur

    **Problème :** Le navigateur bloque les requêtes API en raison de la politique CORS.

    **Solution :** Installez et configurez `cors` :

    ```bash theme={null}
    npm install cors
    ```

    ```javascript theme={null}
    const cors = require('cors');

    app.use(cors({
      origin: 'http://localhost:3000',
    }));
    ```
  </Accordion>
</AccordionGroup>

***

<div id="next-steps">
  ## Prochaines étapes
</div>

Maintenant que vous avez une API protégée, songez à explorer :

* **[Contrôle d’accès basé sur les rôles](https://auth0.com/docs/manage-users/access-control/rbac)** - Mettez en œuvre des permissions granulaires
* **[Pratiques exemplaires en matière d’autorisation des API](https://auth0.com/docs/secure/tokens/access-tokens)** - Découvrez les pratiques exemplaires relatives aux jetons d’accès
* **[Surveillez votre API](https://auth0.com/docs/deploy-monitor/logs)** - Configurez la journalisation et la surveillance
* **[Auth0 Community](https://community.auth0.com/)** - Obtenez de l’aide auprès de la communauté

***

<div id="resources">
  ## Ressources
</div>

* **[express-oauth2-jwt-bearer GitHub](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer)** - Code source et exemples
* **[Documentation d’Express.js](https://expressjs.com/)** - Pour en savoir plus sur Express
* **[Authentification de l’API Auth0](https://auth0.com/docs/secure/tokens/access-tokens)** - Comprendre les jetons d’accès
* **[JWT.io](https://jwt.io/)** - Déboguer et décoder les JWT
