Il existe plusieurs façons d’ajouter une authentification à une API REST :
- Authentification basique : envoi d’un token d’authentification dans l’en-tête de la requête.
- Authentification par jeton : envoi d’un jeton d’authentification dans l’en-tête de la requête.
- Authentification OAuth : utilisation du protocole OAuth pour l’authentification avec des fournisseurs tiers comme Google, Github, etc.
L’authentification est un sujet complexe que nous ne pourrons pas couvrir en détail dans ce tutoriel, mais nous allons voir comment ajouter une authentification basique à notre API REST.
Middleware
Le middleware permet de réaliser des opérations communes à plusieurs routes, comme la vérification d’un token d’authentification par exemple.
Ce concept est utilisé dans de nombreux frameworks web, comme Express.js, pour gérer les requêtes HTTP de manière modulaire.
Authentification (la plus) basique
Pour ajouter une authentification basique à notre API, nous allons utiliser un middleware d’authentification qui va vérifier si le token d’authentification est correct avant de servir la route.
Pour ajouter un middleware à une route, on utilise la méthode app.use(MIDDLEWARE)
.
Dans notre application, on souhaite protéger la route /users
avec une authentification basique.
On va donc ajouter un middleware d’authentification dans le router /routes/users.js
:
1router.use((req, res, next) => {2 // On récupère le header Authorization3 const authorization = req.headers["authorization"];4
5 let authorized = false;6
7 // Basic auth V1, avec un token uniquement non encodé8 if (authorization && authorization === "secret") {9 authorized = true;10 }11
12 if (authorized) next(); // On passe à la route suivante13 else res.status(401).send("Unauthorized"); // Sinon, on renvoie une réponse HTTP 401 (Unauthorized)14
15});
Authentification basique
Dans cet exemple, le middleware vérifie si le token d’authentification est égal à secret
. Si c’est le cas, il appelle la fonction next()
pour passer à la route suivante. Sinon, il renvoie une réponse HTTP 401 (Unauthorized).
Si vous vous rendez sur la route /users
de votre API, vous devriez maintenant obtenir une réponse HTTP 401 si vous n’envoyez pas le bon token d’authentification `
Pour tester l’authentification, vous pouvez ajouter un en-tête Authorization: secret
à votre requête HTTP avec Postman :
Authentification basique v2
Pour complexifier un peu notre authentification, nous allons ajouter un nom d’utilisateur et un mot de passe pour l’authentification.
1router.use((req, res, next) => {2 // On récupère le header Authorization3 const authorization = req.headers["authorization"];4
5 let authorized = false;6
7 // Basic auth V1, avec un token uniquement non encodé8 if (authorization && authorization === "secret") {9 authorized = true;10 }11
12 // Basic auth V2, avec un username et un password13 // Postman envoie le header Authorization avec une valeur de la forme : "Basic <base64-encoded string username:password>"14 // Par exemple : "Basic YWRta"15 // https://learning.postman.com/docs/sending-requests/authorization/authorization-types/#basic-auth16
17 // On va donc devoir séparer la valeur du header, qui est de la forme "Basic <base64-encoded string username:password>"18 // Puis décoder la valeur encodée en base64 pour obtenir le username et le password19 // Puis séparer le username et le password avec le caractère ':'20 // Puis vérifier si le username et le password correspondent à ceux attendus21
22 if (authorization && authorization.startsWith('Basic ')) {23 const base64Credentials = authorization.split(' ')[1];24 const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');25 const [username, password] = credentials.split(':');26
27 if (username === 'admin' && password === 'admin') {28 authorized = true;29 }30 }31
32 if (authorized) next(); // On passe à la route suivante33 else res.status(401).send("Unauthorized"); // Sinon, on renvoie une réponse HTTP 401 (Unauthorized)34});
Dans Postman, il faut maintenant décocher l’option d’en-tête Authorization
et utiliser l’option Authorization
dans l’onglet Authorization
pour envoyer un nom d’utilisateur et un mot de passe encodés en base64.
Testez à nouveau l’API. Vous devriez maintenant obtenir une réponse HTTP 401 si vous n’envoyez pas le bon nom d’utilisateur et le bon mot de passe défini dans le code, à savoir admin:admin
.
Exercice 1
On souhaite ajouter plusieurs utilisateurs à son API REST avec une authentification basique.
- Dans le fichier
routes/users.js
, avant la déclaration du middleware d’authentification, chargez le fichierdata/joueurs.json
:
1const users = require("../data/joueurs.json");
Le fichier joueurs.json
contient un tableau d’utilisateurs avec un nom d’utilisateur et un mot de passe.
- Modifiez le middleware d’authentification pour vérifier si le nom d’utilisateur et le mot de passe correspondent à un des utilisateurs dans le tableau.
- Testez l’authentification avec Postman pour chaque utilisateur.
Exercice 2
Remaniez le fichier data/joueurs.json
et routes/users.js
pour que :
- Les joueurs listés dans
joueurs.json
possède un attributrole
qui contient le rôle de l’utilisateur (admin
oujoueur
) - Modifiez les différentes routes de l’API pour que :
- Les utilisateurs avec le rôle
admin
puissent accéder à la liste des tous les joueurs. - Un utilisateur avec le rôle
joueur
puisse uniquement accéder à sa propre fiche joueur.
Conclusion
-
Dans ce premier exemple, nous avons vu comment ajouter une authentification basique à notre API REST en utilisant un middleware d’authentification.
-
Nous avons vu comment vérifier si le token d’authentification ou bien la paire identifiant/mdp sont corrects avant de servir la route, et comment renvoyer une réponse HTTP 401 (Unauthorized) le cas échéant.
Un paquet node express-basic-auth
existe pour simplifier l’ajout d’une authentification basique à une application Express.js.