Mise en œuvre de l’API Node.js (Apps mobiles + API)

Ce document fait partie du scénario d’architecture Mobile + API et explique comment mettre en œuvre l’API dans Node.js. Le code source complet de la mise en œuvre de l’API Node.js se trouve dans ce dépôt GitHub.

Veuillez vous référer au scénario pour obtenir des informations sur la solution mise en œuvre.

/

Cette implémentation utilise le cadre d’applications Web Express pour construire une API Node.js.

Créer un fichier package.json

Créez un dossier pour votre API, naviguez-y et exécutez  npm init. Ce processus configure votre fichier package.json .

Laissez les paramètres par défaut ou modifiez-les selon votre convenance.

Le package.json  de notre exemple ressemble à ce qui suit :

{
  "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"
}

Was this helpful?

/

Installer les dépendances

Définissez ensuite les dépendances avec les modules suivants :

  • express : ce module ajoute le cadre d’applications Web Express.

  • cors : le présent module ajoute la prise en charge de l’activation du CORS, ce qui est nécessaire car l’API est appelée à partir d’une application à page unique qui s’exécute sur un domaine différent dans un navigateur Web.

  • jwks-rsa : cette bibliothèque récupère les clés de connexion RSA à partir d’un point de terminaison JWKS (JSON Web Key Set). À l’aide de expressJwtSecret, nous pouvons générer un fournisseur de secret qui fournit la bonne clé de connexion à express-jwt en fonction du kid dans l’en-tête JWT. Pour en apprendre davantage, référez-vous au node-jwks-rsa GitHub repository.

  • express-jwt : Le présent module authentifie les requêtes HTTP à l’aide de jetons JWT dans vos applications Node.js. Il fournit plusieurs fonctions qui facilitent le travail avec les JWT. Pour plus d’information, reportez-vous au express-jwt GitHub repository.

  • body-parser : il s’agit d’un logiciel médiateur d’analyse de corps Node.js. Il extrait la totalité du corps d’une requête entrante et l’expose sur req.body comme quelque chose de plus simple avec laquelle interfacer.

Pour installer ces dépendances, suivez les étapes suivantes :

npm install express cors express-jwt jwks-rsa body-parser express-jwt-authz --save

Was this helpful?

/

Implémenter les points de terminaison

Ouvrez votre répertoire API et créez un fichier  server.js . Votre code doit :

  • Obtenir les dépendances.

  • Implémenter le ou les points de terminaison.

  • Lancer le serveur API.

Voici notre exemple d’implémentation :

const express = require('express');
const app = express();
const { expressjwt: jwt } = require('express-jwt');
const jwksRsa = require('jwks-rsa');
const cors = require('cors');
const bodyParser = require('body-parser');

// Enable CORS
app.use(cors());

// Enable the use of request body parsing middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

// Create timesheets API endpoint
app.post('/timesheets', function(req, res){
  res.status(201).send({message: "This is the POST /timesheets endpoint"});
})

// Launch the API Server at localhost:8080
app.listen(8080);

Was this helpful?

/

Lancez votre serveur API en utilisant  node server et envoyez une requête HTTP POST à localhost:8080/timesheets. Vous verrez une réponse JSON avec le message This is the POST /timesheets endpoint.

Nous avons désormais notre point de terminaison, mais tout le monde peut l’appeler. Continuez à l’étape suivante pour voir comment nous pouvons résoudre ce problème.

Pour valider le jeton, utilisez la fonction jwt fournie par le logiciel médiateur express-jwt, et jwks-rsa pour récupérer notre secret Les bibliothèques remplissent les rôles suivants :

  1. express-jwt décode le jeton et achemine la demande, l’en-tête et les données utiles vers  jwksRsa.expressJwtSecret.

  2. jwks-rsa télécharge toutes les clés de connexion à partir du point de terminaison JWKS et vérifie si l’une des clés de connexion correspond à la valeur kid dans l’en-tête du jeton JWT. Si aucune des clés de connexion ne correspond à la valeur kidreçue, une erreur sera générée. Si vous avez une correspondance, transmettez la bonne clé de connexion à express-jwt.

  3. express-jwt poursuit sa propre logique pour valider la signature du jeton, l’expiration, l'audience et l'issuer.

Les étapes que nous suivrons dans notre code sont :

  • Créer la fonction logiciel médiateur pour valider le jeton d’accès.

  • Activez l’utilisation du logiciel médiateur dans nos chemins.

Vous pouvez également écrire du code pour véritablement enregistrer la feuille de temps dans une base de données. Voici notre exemple d’implémentation (certains codes sont omis aux fins de concision) :

// set dependencies - code omitted

// Enable CORS - code omitted

// Create middleware for checking the JWT
const checkJwt = jwt({
  // Dynamically provide a signing key based on the kid in the header and the signing keys provided by the JWKS endpoint
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://{yourDomain}/.well-known/jwks.json`
  }),

  // Validate the audience and the issuer
  audience: '{YOUR_API_IDENTIFIER}', //replace with your API's audience, available at Dashboard > APIs
  issuer: 'https://{yourDomain}/',
  algorithms: [ 'RS256' ]
});

// Enable the use of request body parsing middleware - code omitted

// create timesheets API endpoint - code omitted
app.post('/timesheets', checkJwt, function(req, res){
  var timesheet = req.body;

  // Save the timesheet to the database...

  //send the response
  res.status(201).send(timesheet);
});
// launch the API Server at localhost:8080 - code omitted

Was this helpful?

/

Si nous lançons notre serveur maintenant et effectuons un HTTP POST vers  localhost:8080/timesheets nous obtiendrons le message d’erreur Missing or invalid token (Jeton manquant ou non valide), ce qui est correct, car nous n’avons pas envoyé de jeton d’accès dans notre requête.

Pour tester également le scénario de fonctionnement, nous devons :

  • Obtenir un jeton d’accès. Pour plus d’informations sur la procédure à suivre pour y parvenir, reportez-vous à : Get an Access Token (Obtenir un jeton d’accès).

  • Invoquez l’API en ajoutant un en-tête Authorization (Autorisation) à notre requête avec la valeur Bearer ACCESS_TOKEN (Porteur de jeton d’accès), où ACCESS_TOKEN (jeton d’accès) est la valeur du jeton que nous avons récupéré à la première étape.

Á cette étape, nous ajoutons la possibilité de vérifier si l’application a des autorisations (ou des permissions) et d’utiliser notre point de terminaison afin de créer une feuille de temps. En particulier, nous voulons nous rassurer que le jeton a la bonne portée, qui est batch:upload.

Pour y parvenir, nous utilisons le paquetage  express-jwt-authz Node.js, donc ajoutez-le à votre projet :

npm install express-jwt-authz --save

Was this helpful?

/

Maintenant, ajoutez un appel à jwtAuthz(...) à votre logiciel médiateur pour vous assurer que le jeton JWT contient une permission particulière afin d’exécuter un point de terminaison spécifique.

Nous ajoutons une dépendance supplémentaire. La bibliothèque express-jwt-authz , utilisée conjointement avec express-jwt, valide le jeton JWT et s’assure qu’il possède les autorisations adéquates pour appeler le point de terminaison souhaité. Pour plus d’informations, consultez le  référentiel GitHub express-jwt-authz.

Voici notre exemple d’implémentation (certains codes sont omis aux fins de concision) :

// set dependencies - some code omitted
const jwtAuthz = require('express-jwt-authz');

// Enable CORS - code omitted

// Create middleware for checking the JWT - code omitted

// Enable the use of request body parsing middleware - code omitted

// create timesheets API endpoint
app.post('/timesheets', checkJwt, jwtAuthz(['create:timesheets'], { customUserKey: 'auth' }), function(req, res){
  var timesheet = req.body;

  // Save the timesheet to the database...

  //send the response
  res.status(201).send(timesheet);
})

// launch the API Server at localhost:8080 - code omitted

Was this helpful?

/

Si nous invoquons notre API avec un jeton qui n’inclut pas cette permission, nous devons obtenir le message d’erreur Interdit avec le code d’état HTTP 403. Vous pouvez l’essayer en supprimant cette permission de votre API.

Le logiciel médiateur express-jwt utilisé pour valider le jeton JWT configure également req.user avec les informations contenues dans le jeton JWT. Si vous voulez utiliser la demande sub pour identifier l’utilisateur de manière unique, vous pouvez utiliser req.user.sub. Pour l’application des feuilles de temps, nous voulons utiliser l’adresse courriel de l’utilisateur comme identifiant unique.

Créer une action

Premièrement, créez une nouvelle Action qui ajoutera l’adresse courriel de l’utilisateur au jeton d’accès.

  1. Allez sur Auth0 Dashboard > Actions > Bibliothèqueet sélectionnezCréer une version personnalisée.

  2. Saisissez un Nomdescriptif pour votre action (par exemple, Add email to access token), sélectionnez le déclencheur Connexion/Post-connexion, puis sélectionnez Créer.

  3. Repérez l’éditeur de code des actions, copiez le code JavaScript suivant dans celui-ci, puis sélectionnez Enregistrer le brouillon  pour enregistrer vos modifications.

    exports.onExecutePostLogin = async (event, api) => {
      const namespace = 'https://my-app.example.com';
      api.accessToken.setCustomClaim(`${namespace}/email`, event.user.email);
    }

    Was this helpful?

    /

  4. Dans la barre latérale de l’éditeur de code des actions, sélectionnez Test (icône de lecture), puis sélectionnez Exécuter pour  tester votre code.

  5. Lorsque vous êtes prêt à ce que l’action soit mise en ligne, selectionnez Deploy (Déployer).

Ajoutez votre action au flux de connexion

Ensuite, ajoutez l’action créée au Flux de connexion. Pour savoir comment attacher des actions à des flux, lisez la section Attacher l’action à un flux dans Écrire votre première action.

Récupérer l’identifiant unique

Enfin, à partir de votre API, récupérez la valeur de la demande à partir de req.auth. Utilisez cette valeur comme identifiant d’utilisateur unique à associer aux entrées de la feuille de temps.

app.get('/timesheets', checkJwt, jwtAuthz(['read:timesheets'], { customUserKey: 'auth' }), function(req, res) {
  var timesheet = req.body;

  // Associate the timesheet entry with the current user
  var userId = req.auth['https://api.exampleco.com/email'];
  timesheet.user_id = userId;

  // Save the timesheet to the database...

  //send the response
  res.status(201).send(timesheet);
});

Was this helpful?

/