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

> La mise en œuvre de l’API en Node.js pour le scénario d’architecture Applications serveur + API

# Applications serveur + API : mise en œuvre de l’API en Node.js

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) + "*****MASQUÉ*****";
          }
          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>;
};

Dans le cadre du [scénario d’architecture serveur + API](/docs/fr-ca/get-started/architecture-scenarios/server-application-api), nous allons mettre en œuvre la Timesheets API en Node.js. Veuillez consulter le scénario pour en savoir plus sur la solution mise en œuvre.

Le code source complet de la mise en œuvre de l’API en Node.js se trouve dans [ce dépôt GitHub](https://github.com/auth0-samples/auth0-pnp-exampleco-timesheets/tree/master/timesheets-api/node).

<div id="step-1-define-the-api-endpoint">
  ## Étape 1. Définir le point de terminaison de l’API
</div>

Nous utiliserons le [framework d’application Web Express](http://expressjs.com/) pour créer notre API Node.js.

<div id="create-a-packagejson-file">
  ### Créer un fichier package.json
</div>

Créez un dossier pour votre API, accédez-y, puis exécutez `npm init`. Cela créera votre fichier `package.json`.

Vous pouvez conserver les paramètres par défaut ou les modifier à votre guise.

Voici à quoi ressemble le fichier `package.json` de notre exemple :

```json lines theme={null}
{
  "name": "timesheets-api",
  "version": "1.0.0",
  "description": "API used to add timesheet entries for employees and contractors",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/auth0-samples/auth0-pnp-timesheets.git"
  },
  "author": "Auth0",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/auth0-samples/auth0-pnp-timesheets/issues"
  },
  "homepage": "https://github.com/auth0-samples/auth0-pnp-timesheets#readme"
}
```

<div id="install-the-dependencies">
  ### Installer les dépendances
</div>

Ensuite, nous devons configurer nos dépendances. Nous utiliserons les modules suivants :

* **express** : Ce module ajoute le [framework d’applications web Express](https://expressjs.com/).
* **jwks-rsa** : Cette bibliothèque récupère les clés de signature RSA à partir d’un point de terminaison JWKS (JSON Web Key Set). En utilisant `expressJwtSecret`, nous pouvons générer un fournisseur de secret qui fournira la bonne clé de signature à `express-jwt` selon le `kid` dans le header du <Tooltip tip="JSON Web Token (JWT) : format standard de ID Token (et souvent de jeton d’accès) utilisé pour représenter des claims de façon sécurisée entre deux parties." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=JWT">JWT</Tooltip>. Pour en savoir plus, consultez le [repository GitHub node-jwks-rsa](https://github.com/auth0/node-jwks-rsa).
* **express-jwt** : Ce module vous permet d’authentifier les requêtes HTTP à l’aide de jetons JWT dans vos applications Node.js. Il fournit plusieurs fonctions qui facilitent l’utilisation des JWT. Pour en savoir plus, consultez le [repository GitHub express-jwt](https://github.com/auth0/express-jwt).
* **body-parser** : Il s’agit d’un middleware Node.js d’analyse du body. Il extrait l’intégralité du body d’un stream de request entrant et l’expose dans `req.body` sous une forme plus facile à utiliser. Pour plus d’information et pour découvrir plusieurs solutions de rechange, consultez le repository GitHub de body-parser.

Pour installer ces dépendances, exécutez ce qui suit :

```bash lines theme={null}
npm install express express-jwt jwks-rsa body-parser --save
```

<div id="implement-the-endpoint">
  ### Implémentez le point de terminaison
</div>

Accédez au répertoire de votre API et créez un fichier `server.js`. Votre code doit :

* Définir les dépendances.
* Activer le middleware d’analyse du corps de la requête.
* Implémenter le point de terminaison.
* Démarrer le serveur API.

Voici un exemple de mise en œuvre :

```javascript lines theme={null}
// définir les dépendances
const express = require('express');
const app = express();
const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');
const bodyParser = require('body-parser');

// activer l'utilisation du middleware d'analyse du corps de la requête
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

// créer le point de terminaison API de téléversement des feuilles de temps
app.post('/timesheets/upload', function(req, res){
  res.status(201).send({message: "This is the POST /timesheets/upload endpoint"});
})

// lancer le serveur API à localhost:8080
app.listen(8080);
```

Démarrez votre serveur API à l’aide de `node server`, puis faites une requête HTTP POST à `localhost:8080/timesheets/upload`. Vous devriez voir une réponse JSON contenant le message `This is the POST /timesheets/upload endpoint`.

Nous avons donc maintenant notre point de terminaison, mais n’importe qui peut y faire une requête. Passez au paragraphe suivant pour voir comment régler cela.

<div id="step-2-secure-the-api-endpoint">
  ## Étape 2. Sécuriser le point de terminaison de l’API
</div>

Pour valider notre jeton, nous utiliserons la fonction `jwt`, fournie par le [middleware express-jwt](https://github.com/auth0/express-jwt#usage), ainsi que le package `jwks-rsa` pour récupérer la clé publique depuis Auth0. Ces bibliothèques font ce qui suit :

1. `express-jwt` décodera le jeton et transmettra la requête, l’en-tête et la charge utile à `jwksRsa.expressJwtSecret`.
2. `jwks-rsa` téléchargera ensuite toutes les clés de signature depuis le point de terminaison JWKS et vérifiera si l’une d’elles correspond au `kid` dans l’en-tête du JWT. Si aucune des clés de signature ne correspond au `kid` reçu, une erreur sera générée. En cas de correspondance, nous transmettrons la bonne clé de signature à `express-jwt`.
3. `express-jwt` poursuivra ensuite son propre traitement pour valider la signature du jeton, l’expiration, `audience` et `issuer`.

Les étapes que nous suivrons dans notre code sont les suivantes :

* Créer la fonction middleware pour valider le <Tooltip tip="Jeton d’accès : identifiant d’autorisation, sous la forme d’une chaîne opaque ou d’un JWT, utilisé pour accéder à une API." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=access+token">jeton d’accès</Tooltip>.
* Activer le middleware dans nos routes.

C’est aussi un bon moment pour mettre en œuvre la logique permettant d’enregistrer les entrées de feuille de temps dans une base de données locale, ou dans tout autre mécanisme de stockage que vous préférez. Voici notre exemple de mise en œuvre (une partie du code a été omise par souci de concision) :

export const codeExample = `// définir les dépendances - code omis

// activer l’utilisation du middleware d’analyse du corps de la requête - code omis

// Créer le middleware pour vérifier le JWT
const checkJwt = jwt({
  // Fournir dynamiquement une clé de signature selon le kid dans l’en-tête et les clés de signature fournies par le endpoint JWKS.
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: \`https://{yourDomain}/.well-known/jwks.json\`
  }),

  // Valider l’audience et l’émetteur.
  audience: process.env.AUTH0_AUDIENCE,
  issuer: \`https://{yourDomain}/\`,
  algorithms: ['RS256']
});

// créer le endpoint de l’API Timesheets
app.post('/timesheets/upload', checkJwt, function(req, res){
  var timesheet = req.body;

  // Enregistrer l’entrée de feuille de temps dans la base de données...

  //envoyer la réponse
  res.status(201).send(timesheet);
})

// lancer le serveur API sur localhost:8080 - code omis`;

<AuthCodeBlock children={codeExample} language="javascript" />

Si nous lançons notre serveur maintenant et effectuons une requête HTTP POST vers `localhost:8080/timesheets/upload`, nous devrions obtenir le message d’erreur `Missing or invalid token` (ce qui est tout à fait normal puisque nous n’avons pas envoyé de jeton d’accès dans notre requête).

Pour tester aussi le scénario fonctionnel, nous devons :

* Obtenir un jeton d’accès. Pour savoir comment faire, consultez : [Get an Access Token](/docs/fr-ca/get-started/architecture-scenarios/server-application-api#get-an-access-token)
* Appeler l’API en ajoutant un en-tête `Authorization` à notre requête avec la valeur `Bearer ACCESS_TOKEN` (où `ACCESS_TOKEN` correspond à la valeur du jeton récupéré à la première étape).

<div id="step-3-check-the-client-permissions">
  ## Étape 3. Vérifier les permissions du client
</div>

À cette étape, nous allons ajouter à notre mise en œuvre la possibilité de vérifier si le client a les permissions (ou `scope`) nécessaires pour utiliser notre point de terminaison afin de téléverser une feuille de temps. Plus précisément, nous voulons nous assurer que le jeton a le bon scope, soit `batch:upload`.

Pour ce faire, nous utiliserons le package Node.js `express-jwt-authz`, alors ajoutez-le à votre projet :

```bash lines theme={null}
npm install express-jwt-authz --save
```

Maintenant, il suffit d’ajouter un appel à `jwtAuthz(...)` dans votre middleware pour vous assurer que le JWT contient une portée précise avant d’accéder à un point de terminaison donné. Voici notre exemple de mise en œuvre (une partie du code est omise par souci de concision) :

```javascript lines theme={null}
// définir les dépendances - une partie du code est omise
const jwtAuthz = require('express-jwt-authz');

// Créer le middleware pour la vérification du JWT

// Activer l'utilisation du middleware d'analyse du corps de la requête
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

// Endpoint de téléversement par lot
app.post('/timesheets/upload', checkJwt, jwtAuthz(['batch:upload']), function(req, res){
  var timesheet = req.body;

  // Enregistrer l'entrée de feuille de temps dans la base de données...

  //envoyer la réponse
  res.status(201).send(timesheet);
});

// lancer le serveur API à localhost:8080 - code omis
```

Si nous appelons notre API avec un token qui n’inclut pas cette scope, nous devrions obtenir le message d’erreur Forbidden avec le code d’état HTTP `403`. Vous pouvez le vérifier en retirant cette scope de votre API.

C’est tout ! Vous avez terminé !
