> ## 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 montre 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 />

<Accordion title="Utiliser l’IA pour intégrer Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si vous utilisez un assistant de programmation IA comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification de votre API avec Auth0 en quelques minutes grâce aux [agent skills](https://agentskills.io/home).

  **Installation :**

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

  **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 les points de terminaison de votre API avec la validation des jetons. [Documentation complète sur les agent skills →](/fr-CA/docs/quickstart/agent-skills)
</Accordion>

<Note>
  **Prérequis :** Avant de commencer, assurez-vous d’avoir installé les éléments suivants :

  * **[Node.js](https://nodejs.org/en/download)** 18 LTS ou une version plus récente (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 guide de démarrage rapide fonctionne avec **Express 4.x** et **Express 5.x**.
</Note>

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

Ce guide de démarrage rapide montre comment protéger les points de terminaison d’une API Express.js à l’aide de jetons d’accès JWT. Vous créerez une API sécurisée qui valide les jetons d’accès Auth0, protège les routes et met en place 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 et initialisez un projet Node.js.

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

    Initialisez le projet

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

    Créer la structure du projet

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

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

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

    Ajoutez des scripts de démarrage à 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 locataire 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 Auth0 Dashboard :

    <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 l’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 l’API Auth0
          auth0 apis create `
            --name "My Express API" `
            --identifier https://my-express-api.example.com
          ```
        </CodeGroup>

        <Note>
          Cette commande permet de :

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

        Après la création, 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 locataire 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 à [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Allez à **Applications** → **APIs** → **Create API**
        3. Entrez 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 il doit respecter un format d’URL valide
           * Il n’a pas besoin d’être une vraie URL : c’est simplement un identifiant
        5. Laissez **Signing Algorithm** à **RS256**
        6. Cliquez sur **Create**
        7. Copiez la valeur **Identifier** dans 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 locataire Auth0 (par exemple, `dev-abc123.us.auth0.com`) et `YOUR_API_IDENTIFIER` par l’identifiant de votre API dans le tableau de bord (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 du 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 intergiciel 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 entrants
    * Met `checkJwt` à votre disposition pour protéger des routes individuelles
  </Step>

  <Step title="Créer des routes API" stepNumber={5}>
    Ajoutez des routes publiques et protégées dans 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 jeton d'accès 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 autorisations précises dans le JWT
    * `req.auth.payload` contient les claims décodées du JWT pour les requêtes authentifiées
    * La claim `sub` contient l’identifiant unique de l’utilisateur
  </Step>

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

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

    Votre API s’exécute maintenant à l’adresse [http://localhost:3001](http://localhost:3001).

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

  <Step title="Testez votre API" stepNumber={7}>
    Testez le point de terminaison public (aucune authentification n’est 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 le point de terminaison protégé sans jeton (devrait échouer) :

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

    Vous devriez voir une erreur 401 Non autorisé :

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

    Pour effectuer un test 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>
  **Point de contrôle**

  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 par rapport à votre domaine Auth0 et à l’audience
  4. Fournit des informations sur l’utilisateur à partir des claims du jeton via `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 précis. Vous pouvez exiger des scopes spécifiques 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 les 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 scopes appropriés lorsqu’elle obtient un jeton d’accès.
  </Note>
</Accordion>

<Accordion title="Validation des 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 de claim exacte
  app.get('/api/org/:orgId',
    checkJwt,
    claimEquals('org_id', 'org_123'),
    (req, res) => {
      res.json({ message: 'Organization access granted' });
    }
  );

  // Exige que le claim inclut 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 dans un espace de noms (par exemple, `https://myapp.com/roles`), sauf s’il s’agit 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)">
  Autorisez à la fois l’accès authentifié et l’accès 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 type 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 la commande suivante : `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 » figure bien avant le jeton
    3. Vérifiez que le jeton n’est pas expiré

    ### « Jeton invalide » ou « jwt malformed »

    **Problème :** Le format du jeton est invalide.

    **Solutions :**

    1. Assurez-vous d’utiliser un **jeton d’accès**, et non un jeton d’identité
    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 correspondent 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 des variables correspondent exactement (respect de la casse)

    ### 401 Non autorisé sur 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 échue
    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 l’en-tête Authorization est au format `Bearer YOUR_TOKEN` (avec un espace)

    ### 403 Interdit 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 (Auth0 Dashboard → **Applications** → **APIs** → **Permissions**)
    2. Demandez les scopes lors de l’obtention du 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 stratégie 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, pensez à explorer ce qui suit :

* **[Contrôle d’accès basé sur les rôles](https://auth0.com/docs/manage-users/access-control/rbac)** - Implémentez des autorisations granulaires
* **[Meilleures pratiques pour l’autorisation des API](https://auth0.com/docs/secure/tokens/access-tokens)** - Découvrez les meilleures pratiques relatives aux jetons d’accès
* **[Surveiller votre API](https://auth0.com/docs/deploy-monitor/logs)** - Configurez la journalisation et la surveillance
* **[Communauté Auth0](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/)** - 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
