Terminez d'abord "Leçon 5 : Validation des entrées et gestion des erreurs" pour débloquer cette leçon.Aller à la leçon précédente

Introduction

Le middleware d'authentification se situe entre les requêtes entrantes et vos gestionnaires de routes, vérifiant que les utilisateurs sont bien ceux qu'ils prétendent être avant d'accorder l'accès aux ressources protégées. Dans cette leçon, vous allez construire un middleware d'authentification basé sur JWT et l'appliquer à des routes spécifiques, transformant votre API ouverte en un système sécurisé et prêt pour la production.

Les fonctions middleware ont accès à l'objet request, à l'objet response et à la fonction middleware suivante dans la pile. Le middleware d'authentification inspecte le header Authorization, valide le token, attache les informations utilisateur à la requête, et passe le contrôle au gestionnaire suivant ou rejette la requête.

Construction du middleware d'authentification

Créez une fonction middleware qui extrait et vérifie les tokens JWT. Le middleware vérifie la présence d'un token Bearer dans le header Authorization, le valide à l'aide de votre clé secrète, et attache le payload décodé à l'objet request pour que les gestionnaires en aval puissent l'utiliser.

javascript
const jwt = require('jsonwebtoken');
const authenticate = (req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'No token provided' });
}
const token = authHeader.substring(7);
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid or expired token' });
}
};
module.exports = authenticate;

Le middleware extrait le token en supprimant le préfixe Bearer, le vérifie par rapport à votre secret, et stocke les données utilisateur décodées dans req.user. Si la vérification échoue, il renvoie un statut 401 sans appeler next, arrêtant le pipeline de la requête.

diagramme montrant une requête circulant à travers le middleware d'authentification avec deux branches - un token valide continue vers le gestionnaire de route, un token invalide renvoie une erreur 401

Protéger des routes avec un middleware

Appliquez le middleware d'authentification aux routes qui nécessitent l'identité de l'utilisateur. Vous pouvez protéger des routes individuelles, des groupes de routes ou des routeurs entiers en insérant le middleware avant vos fonctions gestionnaires.

javascript
const express = require('express');
const authenticate = require('./middleware/authenticate');
const router = express.Router();
router.get('/profile', authenticate, (req, res) => {
res.json({
userId: req.user.id,
email: req.user.email,
message: 'This is your protected profile'
});
});
router.post('/posts', authenticate, async (req, res) => {
const post = await createPost({
...req.body,
authorId: req.user.id
});
res.status(201).json(post);
});
router.get('/public', (req, res) => {
res.json({ message: 'This endpoint is public' });
});

Le middleware authenticate s'exécute avant le gestionnaire de route. Les routes sans le middleware restent accessibles publiquement. L'objet req.user rempli par le middleware donne aux gestionnaires l'accès à l'identité de l'utilisateur authentifié.

Contrôle d'accès basé sur les rôles

Étendez votre middleware pour gérer l'autorisation en vérifiant les rôles ou permissions des utilisateurs. Créez une fonction wrapper qui accepte les rôles requis et renvoie un middleware appliquant ces exigences.

javascript
const authorize = (...allowedRoles) => {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({ error: 'Authentication required' });
}
if (!allowedRoles.includes(req.user.role)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
};
router.delete('/users/:id', authenticate, authorize('admin'), async (req, res) => {
await deleteUser(req.params.id);
res.status(204).send();
});
router.put('/posts/:id', authenticate, authorize('admin', 'editor'), async (req, res) => {
const post = await updatePost(req.params.id, req.body);
res.json(post);
});

Le middleware authorize suppose que authenticate a déjà été exécuté et a attaché req.user. Il vérifie le rôle de l'utilisateur par rapport aux valeurs autorisées et renvoie 403 Forbidden si le rôle ne correspond pas. Enchaînez plusieurs fonctions middleware pour imposer à la fois l'authentification et l'autorisation.

Gestion des erreurs et rafraîchissement des tokens

Gérez les scénarios d'authentification courants avec élégance. Faites la distinction entre tokens manquants, invalides et expirés pour fournir un retour d'information clair. Envisagez de mettre en œuvre des refresh tokens pour les sessions de longue durée.

javascript
const authenticate = (req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
error: 'No token provided',
code: 'TOKEN_MISSING'
});
}
const token = authHeader.substring(7);
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
if (error.name === 'TokenExpiredError') {
return res.status(401).json({
error: 'Token expired',
code: 'TOKEN_EXPIRED'
});
}
return res.status(401).json({
error: 'Invalid token',
code: 'TOKEN_INVALID'
});
}
};

Des réponses d'erreur structurées avec des codes d'erreur aident les clients à gérer les différents modes d'échec de manière appropriée. Les tokens expirés peuvent déclencher un flux de rafraîchissement, tandis que les tokens invalides nécessitent une nouvelle authentification.

Résumé

Le middleware d'authentification centralise la logique de sécurité et l'applique de manière cohérente dans toute votre API. En extrayant et vérifiant les tokens JWT, en attachant les informations utilisateur aux requêtes, et en imposant un contrôle d'accès basé sur les rôles, vous transformez des endpoints ouverts en un système sécurisé. Exécutez toujours l'authentification avant l'autorisation, renvoyez des réponses d'erreur claires, et envisagez des stratégies d'expiration et de rafraîchissement des tokens pour les déploiements en production.

Entraînement

Point de contrôle de la leçon

Révisez la leçon et recevez des conseils sur votre travail.

0/1
Répondu · 0/1