Dans le développement backend, il est essentiel de contrôler l’accès aux ressources pour garantir la sécurité des données. Une API doit pouvoir restreindre certaines actions en fonction des rôles et autorisations des utilisateurs.
Dans cet article, nous allons voir comment gérer les permissions dans une API Node.js avec Express, en mettant en place un système de rôles pour sécuriser les routes et limiter l’accès aux utilisateurs autorisés.
1. Pourquoi gérer les permissions dans une API ?
Toutes les API ne sont pas accessibles à tous les utilisateurs. Selon leur rôle (admin, utilisateur, modérateur, invité), certaines actions doivent être limitées.
Prenons un exemple :
- ✅ Un administrateur peut ajouter, modifier et supprimer des utilisateurs.
- ✅ Un utilisateur standard peut seulement modifier son propre compte.
- ❌ Un invité ne peut pas accéder aux ressources privées.
Sans un système de permissions, toute personne ayant accès à l’API pourrait modifier des données sensibles, ce qui représente un risque de sécurité majeur.
2. Mettre en place un système de rôles
Nous allons définir un système de rôles basé sur des tokens JWT (JSON Web Token).
2.1 Installation des dépendances nécessaires
Avant de commencer, installez les bibliothèques suivantes :
npm install express jsonwebtoken bcryptjs dotenv
- jsonwebtoken : Permet de générer et vérifier des tokens JWT.
- bcryptjs : Hache les mots de passe pour sécuriser les comptes utilisateurs.
- dotenv : Stocke les variables d’environnement.
3. Système d’authentification avec JWT
Nous allons créer une API qui gère l’inscription, la connexion et les rôles des utilisateurs.
3.1 Stockage des utilisateurs en mémoire
Dans server.js, nous allons créer une liste d’utilisateurs avec des rôles différents :
require('dotenv').config();
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const app = express();
app.use(express.json());
const utilisateurs = []; // Simule une base de données
const SECRET_KEY = process.env.SECRET_KEY || "super_secret_key";
3.2 Inscription avec un rôle défini
Lorsqu’un utilisateur s’inscrit, il doit avoir un rôle défini (ex. utilisateur
ou admin
).
app.post('/inscription', async (req, res) => {
const { nom, email, password, role } = req.body;
if (!["admin", "utilisateur"].includes(role)) {
return res.status(400).json({ message: "Rôle invalide" });
}
const hashedPassword = await bcrypt.hash(password, 10);
utilisateurs.push({ nom, email, password: hashedPassword, role });
res.status(201).json({ message: 'Utilisateur inscrit avec succès' });
});
✅ Le mot de passe est haché avec bcrypt pour la sécurité.
✅ L’utilisateur choisit son rôle (admin
ou utilisateur
).
✅ On empêche l’ajout d’un rôle non autorisé.
3.3 Connexion et génération du token JWT
Lorsqu’un utilisateur se connecte, il reçoit un token JWT contenant son rôle.
app.post('/connexion', async (req, res) => {
const { email, password } = req.body;
const utilisateur = utilisateurs.find(u => u.email === email);
if (!utilisateur || !await bcrypt.compare(password, utilisateur.password)) {
return res.status(401).json({ message: 'Email ou mot de passe incorrect' });
}
const token = jwt.sign({ email: utilisateur.email, role: utilisateur.role }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
});
✅ Le token JWT contient le rôle de l’utilisateur.
✅ Le token expire après 1 heure pour plus de sécurité.
4. Vérifier les permissions avec un middleware
Nous allons créer un middleware qui protège les routes en fonction du rôle de l’utilisateur.
const verifierToken = (req, res, next) => {
const token = req.headers['authorization'];
if (!token) return res.status(403).json({ message: 'Accès refusé' });
jwt.verify(token.split(' ')[1], SECRET_KEY, (err, decoded) => {
if (err) return res.status(401).json({ message: 'Token invalide' });
req.utilisateur = decoded;
next();
});
};
✅ Vérifie que le token est présent et valide.
✅ Ajoute les informations utilisateur (email
, role
) à la requête.
5. Protéger les routes selon les rôles
5.1 Middleware pour vérifier les rôles
Ajoutons un middleware qui autorise l’accès aux routes en fonction du rôle de l’utilisateur.
const autoriserRole = (roles) => {
return (req, res, next) => {
if (!roles.includes(req.utilisateur.role)) {
return res.status(403).json({ message: 'Accès interdit' });
}
next();
};
};
✅ L’utilisateur ne peut accéder à la route que si son rôle est autorisé.
5.2 Routes sécurisées selon les permissions
Ajoutons des routes sécurisées :
// Route accessible uniquement aux administrateurs
app.get('/admin', verifierToken, autoriserRole(['admin']), (req, res) => {
res.json({ message: "Bienvenue dans la section admin" });
});
// Route accessible aux administrateurs et utilisateurs
app.get('/profil', verifierToken, autoriserRole(['admin', 'utilisateur']), (req, res) => {
res.json({ message: `Bienvenue ${req.utilisateur.email}` });
});
✅ Les administrateurs peuvent accéder à toutes les routes.
✅ Les utilisateurs normaux n’ont pas accès à la route /admin
.
6. Tester l’API avec Postman
1️⃣ S’inscrire en tant qu’admin ou utilisateur
{
"nom": "Alice",
"email": "alice@example.com",
"password": "motdepasse",
"role": "admin"
}
2️⃣ Se connecter pour obtenir un token JWT
{
"email": "alice@example.com",
"password": "motdepasse"
}
3️⃣ Accéder à /admin
avec un token valide
- Si l’utilisateur est
admin
→ ✅ Accès autorisé - Si l’utilisateur est
utilisateur
→ ❌ Accès refusé
7. Sources
- JWT - Introduction et documentation : https://jwt.io/introduction/ (page consultée le 14 février 2025).
- Express.js - Middleware Authorization : https://expressjs.com/en/guide/using-middleware.html (page consultée le 14 février 2025).
- Mozilla Developer Network - Security Best Practices : https://developer.mozilla.org/en-US/docs/Web/Security (page consultée le 14 février 2025).
Commentaires1
Commentaire
Ton article offre une introduction claire et pratique à la gestion des permissions dans une API Node.js avec Express. Il explique bien pourquoi un système de rôles est essentiel pour sécuriser les routes et structurer l'accès aux ressources. L'utilisation de JWT pour l'authentification et la mise en place de middlewares pour gérer les autorisations sont bien détaillées. Une amélioration possible serait d'expliquer comment stocker les utilisateurs dans une base de données pour une application plus réaliste, ou d’ajouter des tests automatisés pour valider les permissions.