Sécuriser une application Express.js avec JWT
La sécurisation des applications web est un enjeu crucial dans le développement moderne, et Express.js, l’un des frameworks les plus utilisés pour créer des applications Node.js, ne fait pas exception. L’utilisation de JWT (JSON Web Token) représente une solution efficace pour gérer l’authentification des utilisateurs. Elle permet de s’assurer que seules les personnes autorisées peuvent accéder à certaines ressources ou routes. Dans ce contexte, nous allons explorer comment intégrer JWT dans une application Express.js pour mieux sécuriser les échanges et garantir l’intégrité des données.
Dans cet article, nous allons explorer comment sécuriser une application web développée avec Express.js à l’aide de JSON Web Tokens (JWT). Nous aborderons les bases de JWT, l’installation des dépendances nécessaires, la création d’une API simple pour l’inscription et la connexion des utilisateurs, ainsi que la mise en place de la protection des routes. Grâce à ces étapes, vous serez capable d’implémenter une authentification sécurisée pour vos applications Node.js.
Qu’est-ce que JWT ?
JWT, ou JSON Web Token, est une norme ouverte permettant de transmettre des informations de manière sécurisée sous forme de JSON. Sa structure se compose de trois parties distinctes : header, payload et signature, chacune jouant un rôle crucial dans la sécurité de l’échange des informations.
La première partie, le header, spécifie le type de token et l’algorithme utilisé pour signer le token (par exemple, HMAC SHA256). La seconde partie, le payload, contient les déclarations ou informations relatives à l’utilisateur, telles que son identifiant ou son nom d’utilisateur. Enfin, la signature permet de vérifier l’intégrité du token en utilisant un secret partagé.
Installation des dépendances
Pour commencer, vous aurez besoin de créer un nouveau projet Node.js et d’installer certains modules essentiels. Depuis votre terminal, créez un nouveau dossier puis initialisez votre projet avec la commande npm init -y. Cela générera un fichier package.json.
Ensuite, vous devrez installer les dépendances suivantes en exécutant :
<!– wp:code {"content":"nnpm install express jsonwebtoken bcryptjs body-parser corsn« } –>
npm install express jsonwebtoken bcryptjs body-parser cors
Voici un aperçu de chaque module :
- express : Le framework HTTP pour construire des applications web.
- jsonwebtoken : Pour créer et vérifier des JWT.
- bcryptjs : Pour le hachage et la comparaison sécurisés des mots de passe.
- body-parser : Pour analyser les corps de requête entrantes.
- cors : Pour gérer le partage de ressources entre origines.
Création de l’application Express
Après l’installation des dépendances, vous pouvez créer un fichier nommé server.js pour initialiser votre application Express. Ajoutez les lignes de code suivantes au fichier :
<!– wp:code {"content":"nconst express = require('express');nconst bodyParser = require('body-parser');nconst cors = require('cors');nnconst app = express();nconst PORT = 5000;nn// Middleware pour analyser les corps des requu00eates entrantesnapp.use(cors());napp.use(bodyParser.json());nn// Du00e9marrage du serveurnapp.listen(PORT, () => {n console.log(`Server is running on port ${PORT}`);n});n« } –>
const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const app = express(); const PORT = 5000; // Middleware pour analyser les corps des requêtes entrantes app.use(cors()); app.use(bodyParser.json()); // Démarrage du serveur app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
Ce code met en place un serveur Express basique. Grâce à l’utilisation de middleware cors et body-parser, votre application pourra traiter les requêtes JSON et contrôler les échanges interdomaines.
Enregistrement et connexion des utilisateurs
Pour gérer les utilisateurs, nous allons créer une fonction d’enregistrement qui permet de créer de nouveaux comptes en toute sécurité. Grâce à bcryptjs, nous allons hacher les mots de passe avant de les stocker.
<!– wp:code {"content":"nconst bcrypt = require('bcryptjs');nnlet users = []; // Stockage en mu00e9moire des utilisateursnn// Registre un nouvel utilisateurnapp.post('/register', async (req, res) => {n const { username, password } = req.body;nn // Hachage du mot de passen const hashedPassword = await bcrypt.hash(password, 10);nn // Stockage de l'utilisateur avec le mot de passe hachu00e9n users.push({ username, password: hashedPassword });nn res.status(201).json({ message: 'User registered successfully!' });n});n« } –>
const bcrypt = require('bcryptjs'); let users = []; // Stockage en mémoire des utilisateurs // Registre un nouvel utilisateur app.post('/register', async (req, res) => { const { username, password } = req.body; // Hachage du mot de passe const hashedPassword = await bcrypt.hash(password, 10); // Stockage de l'utilisateur avec le mot de passe haché users.push({ username, password: hashedPassword }); res.status(201).json({ message: 'User registered successfully!' }); });
Dans cet extrait de code, le mot de passe de chaque nouvel utilisateur est haché avant d’être ajouté au tableau users. Cela garantit que les mots de passe ne sont jamais stockés en texte clair.
Génération de JWT lors de la connexion
Après l’enregistrement, les utilisateurs doivent pouvoir se connecter et obtenir un token JWT. Voici comment vous pouvez le faire :
<!– wp:code {"content":"nconst jwt = require('jsonwebtoken');nconst secretKey = 'your-secret-key'; // Stockez-le en su00e9curitu00e9nn// Connexion de l'utilisateur et gu00e9nu00e9ration du JWTnapp.post('/login', async (req, res) => {n const { username, password } = req.body;nn const user = users.find(u => u.username === username);n if (!user) return res.status(400).json({ message: 'Invalid credentials' });nn const isPasswordValid = await bcrypt.compare(password, user.password);n if (!isPasswordValid) return res.status(400).json({ message: 'Invalid credentials' });nn const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });nn res.json({ token });n});n« } –>
const jwt = require('jsonwebtoken'); const secretKey = 'your-secret-key'; // Stockez-le en sécurité // Connexion de l'utilisateur et génération du JWT app.post('/login', async (req, res) => { const { username, password } = req.body; const user = users.find(u => u.username === username); if (!user) return res.status(400).json({ message: 'Invalid credentials' }); const isPasswordValid = await bcrypt.compare(password, user.password); if (!isPasswordValid) return res.status(400).json({ message: 'Invalid credentials' }); const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' }); res.json({ token }); });
Lorsque l’utilisateur se connecte, son nom d’utilisateur et son mot de passe sont validés. Si l’authentification réussit, un token JWT est généré et renvoyé à l’utilisateur. Ce token sera utilisé pour les requêtes futures sur les routes protégées.
Protéger les routes avec un middleware JWT
Pour protéger des routes spécifiques, vous devez créer un middleware qui vérifie la présence et la validité du token JWT fourni par l’utilisateur dans l’en-tête de la requête.
<!– wp:code {"content":"nconst verifyToken = (req, res, next) => {n const token = req.header('Authorization');n if (!token) return res.status(401).json({ message: 'Access Denied' });nn try {n const verified = jwt.verify(token.split(' ')[1], secretKey);n req.user = verified;n next();n } catch (err) {n res.status(400).json({ message: 'Invalid Token' });n }n};n« } –>
const verifyToken = (req, res, next) => { const token = req.header('Authorization'); if (!token) return res.status(401).json({ message: 'Access Denied' }); try { const verified = jwt.verify(token.split(' ')[1], secretKey); req.user = verified; next(); } catch (err) { res.status(400).json({ message: 'Invalid Token' }); } };
Le middleware verifyToken vérifie le token et, en cas de succès, permet à l’utilisateur d’accéder aux routes protégées. Sinon, il renvoie une erreur 401 ou 400 selon le problème rencontré.
Mise en place des routes protégées
Pour appliquer le middleware d’authentification, ajoutez-le à toute route que vous souhaitez protéger. Voici un exemple d’implémentation :
<!– wp:code {"content":"napp.get('/dashboard', verifyToken, (req, res) => {n res.json({ message: `Welcome to the dashboard, ${req.user.username}!` });n});n« } –>
app.get('/dashboard', verifyToken, (req, res) => { res.json({ message: `Welcome to the dashboard, ${req.user.username}!` }); });
Cette route /dashboard, lorsqu’elle est demandée, va d’abord passer par le middleware verifyToken, garantissant que seul un utilisateur authentifié peut accéder à son contenu.
Tests de l’application
Pour tester l’application, vous pouvez utiliser des outils comme Postman ou curl. Commencez par enregistrer un nouvel utilisateur :
<!– wp:code {"content":"ncurl -X POST http://localhost:5000/register -H "Content-Type: application/json" -d '{"username": "user", "password": "password123"}'n« } –>
curl -X POST http://localhost:5000/register -H "Content-Type: application/json" -d '{"username": "user", "password": "password123"}'
Ensuite, effectuez une connexion :
<!– wp:code {"content":"ncurl -X POST http://localhost:5000/login -H "Content-Type: application/json" -d '{"username": "user", "password": "password123"}'n« } –>
curl -X POST http://localhost:5000/login -H "Content-Type: application/json" -d '{"username": "user", "password": "password123"}'
Enfin, utilisez le JWT reçu pour accéder à la route protégée :
<!– wp:code {"content":"ncurl -X GET http://localhost:5000/dashboard -H "Authorization: Bearer your-jwt-token"n« } –>
curl -X GET http://localhost:5000/dashboard -H "Authorization: Bearer your-jwt-token"
Si le token est valide, vous obtiendrez un message de bienvenue indiquant que l’utilisateur est connecté.
Aspect | Détails |
---|---|
Authentification | Utilisation de JWT pour vérifier l’identité des utilisateurs. |
Token | Création d’un jeton signé pour chaque utilisateur authentifié. |
Méthode de Vérification | Utilisation de middleware pour valider le token sur les routes protégées. |
Stockage | Le token est stocké côté client, réduisant la charge serveur. |
Expiration | Configuration d’une durée d’expiration des tokens pour renforcer la sécurité. |
Récupération | Avoir des mécanismes pour régénérer ou rafraîchir le token. |
Librairie | Utilisation de jsonwebtoken pour la gestion des JWT. |
Chiffrement | Considérer le chiffrement des mots de passe avec bcrypt. |
« `html
Assurer la Sécurité d’une Application Express.js
Pour sécuriser une application Express.js, l’utilisation de JSON Web Token (JWT) se présente comme une solution efficiente. Ce mécanisme permet une gestion de l’authentification simplifiée tout en garantissant un haut niveau de sécurité. En fournissant un moyen pour les utilisateurs de s’authentifier sans nécessiter de sessions côté serveur, les JWT rendent les applications plus rapides et facilement scalables.
Le processus commence par l’enregistrement des utilisateurs, où les mots de passe doivent être hachés pour protéger les données sensibles. Une fois que l’utilisateur est enregistré, il peut se connecter en soumettant ses identifiants. En cas de succès, un token JWT est généré, le validant pour accéder aux différentes routes protégées de l’application.
Les routes protégées utilisent des middlewares pour vérifier la validité du token, assurant ainsi que seules les requêtes authentifiées ont accès aux ressources sensibles. En intégrant le JWT avec des mesures de sécurité supplémentaires, telles que le chiffrement HTTPS et l’expiration régulée des tokens, les développeurs peuvent construire des applications robustes face aux menaces de sécurité potentielles.