Il existe un moment particulier dans la vie d’un développeur où tout devient sérieux : celui où il faut gérer l’authentification. Tant que votre application Node.js affiche “Hello world”, tout va bien. Mais dès que vous ouvrez une porte aux utilisateurs, vous devez la sécuriser. Cela peut sembler intimidant, un peu comme quand on ouvre pour la première fois le capot d’une voiture en pensant y comprendre quelque chose. Pourtant, avec les bonnes explications, tout devient clair et même agréable.
- Comprendre comment sécuriser efficacement les mots de passe pour protéger ses utilisateurs dès la création du projet.
- Savoir mettre en place une authentification fiable avec tokens pour gérer les accès sans complexité inutile.
- Être capable de structurer proprement son code Node.js afin de créer un système d’identification clair, évolutif et facile à maintenir.
L’objectif de ce chapitre est de vous accompagner pas à pas, en partant de zéro, pour vous apprendre à construire un système d’authentification solide avec Node.js. Nous allons prendre le temps, pour que même un débutant complet puisse suivre sans jamais se sentir perdu. Vous verrez comment protéger les mots de passe avec un hash, comment générer des tokens, comment organiser votre code et pourquoi certaines étapes sont indispensables. Et surtout, vous comprendrez ce que vous faites, au lieu de simplement copier-coller un tutoriel trouvé au hasard.
Si vous débutez en développement web ou si vous souhaitez renforcer votre compréhension de la sécurité côté serveur, vous allez apprendre à créer l’une des fondations essentielles de n’importe quelle application web moderne : une authentification fiable, propre, et qui ne laissera pas votre base de données se faire ouvrir comme une boîte de sardines.
- Pourquoi réfléchir à la sécurité dès le début
- Un projet Node.js propre pour accueillir l’authentification
- Créer un serveur minimal
- Construire la route d’inscription : accepter, vérifier et hasher le mot de passe
- Construire la route login : vérifier le mot de passe et générer un token
- Vérifier un token : protéger les routes sensibles
- Éviter les erreurs courantes : les pièges classiques en authentification Node.js
- Adopter les bonnes pratiques : renforcer la sécurité de votre authentification Node.js
- Organiser proprement votre architecture Node.js pour l’authentification
- Un petit projet complet : l’authentification Node.js de A à Z
- Les routes
- Le middleware d’authentification
- Le point d’entrée
- Consolider vos bases pour aller plus loin
Lorsque l’on parle d’authentification avec Node.js, plusieurs concepts travaillent ensemble. Avant de plonger dans le code, prenons quelques minutes pour comprendre ces idées clés, car elles guideront tout le reste de votre apprentissage.
Pourquoi réfléchir à la sécurité dès le début
Il est fréquent, lorsque l’on débute, de se dire qu’on ajoutera la sécurité plus tard. Pourtant, c’est un peu comme construire une maison sans fondations en espérant revenir les couler ensuite, quand le toit sera posé. En pratique, ce n’est pas possible. L’authentification, c’est ce qui permet de vérifier qu’un utilisateur est bien celui qu’il prétend être. Et cela implique de gérer des informations sensibles, en particulier les mots de passe.
À mes débuts, j’avais construit un petit site de test en stockant les mots de passe en clair dans ma base MySQL. Depuis ce jour-là que j’ai compris que ce simple choix pouvait transformer une application en catastrophe ambulante.
Sécuriser les mots de passe n’est pas une option. C’est une base incontournable.
Le rôle du hash dans la protection des mots de passe
Vous verrez souvent le mot hash associé à la sécurité des mots de passe. Le hash est une transformation irréversible : on applique une formule mathématique au mot de passe pour obtenir une suite de caractères complètement différente. Cette suite ne peut pas être reconvertie en mot de passe original, même par celui qui gère la base de données.
Si vous stockez le mot de passe “soleil123”, celui-ci n’apparaît pas dans votre base. À la place, vous aurez quelque chose du genre :
45d4d1fe4a77f21abb4e7e2e4c9a8efd...Cela n’a aucun sens lisible, et c’est exactement ce qu’on veut.
Pourquoi pas un simple hash MD5 ?
Parce qu’il existe aujourd’hui des tables de correspondance qui permettent de retrouver très facilement un mot de passe à partir d’un hash MD5 ou SHA1. Ces algorithmes ne sont plus adaptés à la sécurité moderne.
Node.js propose des outils comme bcrypt, spécialement conçu pour sécuriser les mots de passe. Il ajoute un “sel”, ralentit le processus pour compliquer les attaques, et rend la tâche très difficile à un attaquant.
À quoi servent les tokens ?
Une fois qu’un utilisateur est connecté, vous devez vous souvenir qu’il est bien authentifié pour les prochaines requêtes. Mais vous ne pouvez pas renvoyer le mot de passe à chaque fois. Vous allez donc créer un jeton, ou token.
Ce token représente l’utilisateur de manière temporaire. Il contient un identifiant, une date d’expiration et éventuellement d’autres informations. Lorsque le serveur reçoit une requête portant ce token, il peut vérifier que l’utilisateur a bien le droit d’accéder à cette ressource.
Les tokens sont généralement créés avec JWT (JSON Web Token). Ils sont signés avec une clé secrète pour éviter la falsification.
Un projet Node.js propre pour accueillir l’authentification
Maintenant que vous savez où vous allez, il est temps de passer aux choses concrètes. Avant de bâtir l’authentification, nous devons poser une base solide.
Initialiser un projet Node.js
Vous n’avez besoin que de Node.js, d’un éditeur de code (VS Code fait très bien l’affaire), et d’un terminal.
Dans un dossier vide, commencez par initialiser votre projet :
npm init -yCette commande crée un fichier package.json qui contiendra les informations essentielles de votre projet.
Installer les modules nécessaires
Nous allons avoir besoin de plusieurs modules :
- Express pour créer notre serveur
- bcrypt pour hasher les mots de passe
- jsonwebtoken pour générer les tokens
- dotenv pour stocker les variables secrètes
Installez tout cela avec :
npm install express bcrypt jsonwebtoken dotenvUne fois l’installation terminée, vous avez tout le nécessaire pour commencer à construire votre système d’authentification.
Tout comprendre de NPM, Package et module
Créer un serveur minimal
Dans un fichier app.js, écrivez :
const express = require('express');
const app = express();
app.use(express.json());
app.listen(3000, () => {
console.log('Serveur lancé sur le port 3000');
});Lancez le serveur :
node app.jsVous devriez voir le message s’afficher dans votre terminal. Vous avez maintenant un serveur Express avec Node.js opérationnel, prêt à accueillir du code d’authentification.
Construire la route d’inscription : accepter, vérifier et hasher le mot de passe
Lorsqu’un utilisateur souhaite créer un compte, il va envoyer son email et son mot de passe à votre serveur Node.js. À ce moment précis, deux choses sont essentielles : vérifier que les données sont valides, puis protéger le mot de passe avant de l’enregistrer. Rien ne doit transiter ou être stocké en clair.
Comprendre le rôle de la route d’inscription
La route d’inscription est la première rencontre entre votre futur utilisateur et votre système d’authentification. C’est comme la porte d’entrée d’un immeuble : vous devez décider qui peut entrer, vérifier qu’il ne s’agit pas d’un intrus et vous assurer que tout est enregistré de manière sécurisée.
Créer cette route revient à faire trois actions :
- Récupérer les données de l’utilisateur envoyées dans la requête.
- Vérifier que ces données sont valides.
- Convertir le mot de passe en hash avec bcrypt avant de l’enregistrer.
Chaque étape est vitale. Sauter la validation peut ouvrir la voie à des injections SQL. Oublier le hash du mot de passe, c’est exposer vos utilisateurs en cas de fuite. Ne pas vérifier l’unicité de l’email peut aussi provoquer des comportements étranges et frustrants pour vos utilisateurs.
Installer et utiliser bcrypt pour hasher les mots de passe
bcrypt est un module très utilisé dans l’écosystème Node.js. Il permet de transformer un mot de passe en une chaîne incompréhensible et non réversible. Le principe est simple, mais la logique sous-jacente est sophistiquée : il ajoute un sel, répète plusieurs opérations et rend chaque tentative d’attaque extrêmement coûteuse en temps.
Le “coût” du hash est modulable. Plus il est élevé, plus le hachage est long et sécurisé. Pour un usage classique, un coût entre 10 et 12 est suffisant. Au-dessus, votre API risque de ralentir côté serveur.
Exemple concret : la route d’inscription
Commençons par créer un dossier routes, puis un fichier auth.js à l’intérieur. Voici un exemple clair et complet, parfaitement adapté aux débutants :
const express = require('express');
const bcrypt = require('bcrypt');
const router = express.Router();
// Exemple de stockage en mémoire pour l'exemple
// Dans un vrai projet, on utilisera une base de données
const users = [];
router.post('/register', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: 'Email et mot de passe requis.' });
}
const userExists = users.find(user => user.email === email);
if (userExists) {
return res.status(400).json({ message: 'Cet email est déjà utilisé.' });
}
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = {
email,
password: hashedPassword
};
users.push(newUser);
res.status(201).json({ message: 'Utilisateur créé avec succès.' });
});
module.exports = router;Cet exemple utilise un simple tableau pour simuler une base de données. Dans votre vrai projet, vous utiliserez probablement une base de données MySQL, MongoDB ou PostgreSQL, mais la logique reste exactement la même.
Comment relier cette route à votre serveur ?
Dans votre app.js :
const express = require('express');
const authRoutes = require('./routes/auth');
const app = express();
app.use(express.json());
app.use('/auth', authRoutes);
app.listen(3000, () => {
console.log('Serveur lancé sur le port 3000');
});Vous pouvez désormais appeler votre route d’inscription avec Postman ou un formulaire frontend.
Construire la route login : vérifier le mot de passe et générer un token
L’utilisateur existe désormais dans votre base. La prochaine étape consiste à lui permettre de se connecter.
Le fonctionnement du login en Node.js
Le login repose sur une idée simple : comparer le mot de passe que l’utilisateur envoie avec le hash déjà stocké. Bien entendu, vous n’allez jamais dé-hasher le mot de passe : vous allez comparer le mot de passe fourni avec le hash, grâce à bcrypt.compare.
-> Si la comparaison réussit, vous générez un token. Sinon, vous refusez la connexion.
Chaque étape doit être précise, car une mauvaise implémentation peut soit bloquer tout le monde, soit laisser entrer n’importe qui.
Exemple complet de route login
Ajoutons ceci à votre fichier auth.js :
const jwt = require('jsonwebtoken');
require('dotenv').config();
router.post('/login', async (req, res) => {
const { email, password } = req.body;
const user = users.find(user => user.email === email);
if (!user) {
return res.status(400).json({ message: 'Email ou mot de passe incorrect.' });
}
const passwordIsValid = await bcrypt.compare(password, user.password);
if (!passwordIsValid) {
return res.status(400).json({ message: 'Email ou mot de passe incorrect.' });
}
const token = jwt.sign(
{ email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
res.status(200).json({ message: 'Connexion réussie.', token });
});Vous remarquerez que le token contient uniquement l’email dans cet exemple. Vous pouvez y ajouter un id, un rôle utilisateur, ou n’importe quelle donnée non sensible.
N’oubliez pas de créer un fichier .env à la racine du projet :
JWT_SECRET=s3cr3t123Et dans votre app.js, chargez-le en ajoutant :
require('dotenv').config();Vérifier un token : protéger les routes sensibles
Un système d’authentification n’a pas d’utilité si tout le monde peut quand même accéder aux routes sécurisées sans vérifier son identité. C’est ici que le middleware d’authentification intervient.

Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?Rôle du middleware d’authentification
Un middleware agit comme un vigile devant une porte. Avant qu’une requête n’accède à votre route, il inspecte le token envoyé par l’utilisateur, le vérifie, et décide s’il laisse passer ou non.
Ce middleware doit être clair, propre et facilement réutilisable.
Exemple de middleware simple et efficace
Créez un fichier middleware/auth.js :
const jwt = require('jsonwebtoken');
module.exports = function(req, res, next) {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ message: 'Token manquant.' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
return res.status(401).json({ message: 'Token invalide ou expiré.' });
}
};Ce middleware vérifie trois choses :
- Le token est présent
- Le token est valide
- Le token n’a pas expiré
Si tout va bien, il ajoute les informations du token à req.user pour qu’elles soient utilisables dans la route suivante.
Exemple de route protégée
Dans app.js :
const authMiddleware = require('./middleware/auth');
app.get('/dashboard', authMiddleware, (req, res) => {
res.json({ message: `Bienvenue ${req.user.email}` });
});Si vous essayez d’accéder à cette route sans fournir de token, vous serez bloqué. Si vous envoyez un token expiré ou modifié, vous serez également rejeté.
Éviter les erreurs courantes : les pièges classiques en authentification Node.js
Même avec les meilleures intentions du monde, un système d’authentification peut devenir fragile si l’on tombe dans certains pièges classiques. Les débutants sont souvent victimes de ces erreurs, non pas parce qu’ils manquent de sérieux, mais parce que la sécurité est un domaine où un simple détail peut tout changer. Prenons le temps d’examiner ces écueils, afin que vous construisiez un système robuste sans mauvaise surprise.
Stocker les mots de passe en clair
C’est l’une des fautes les plus graves, et pourtant elle est encore très fréquente. Certains développeurs, pressés par le temps, se disent qu’ils ajouteront le hash plus tard. En réalité, ce “plus tard” ne vient jamais, et le jour où la base fuit, c’est la catastrophe. Même un petit projet personnel mérite une sécurité minimale.
Pensez que le mot de passe n’est jamais seulement un mot de passe. Beaucoup d’utilisateurs réutilisent les mêmes identifiants partout : leurs réseaux sociaux, leur messagerie, leurs comptes bancaires. Leur offrir une sécurité solide, c’est leur éviter des ennuis potentiellement très graves.
Utiliser un hash trop faible comme MD5 ou SHA1
MD5 est aujourd’hui aussi utile pour protéger un mot de passe qu’un cadenas en plastique pour sécuriser une banque. On peut retrouver un MD5 en quelques secondes, grâce à des tables de correspondance existantes. bcrypt, lui, est conçu spécialement pour gérer des passwords, avec une lenteur volontaire qui rend les attaques brutales difficiles.
MD5 a peut-être eu son heure de gloire il y a quinze ans, mais aujourd’hui il doit rester dans les livres d’histoire. Pour votre système Node.js, oubliez-le complètement.
Oublier l’expiration du token
Un token sans date d’expiration est une porte grande ouverte. Imaginez qu’un utilisateur se connecte depuis un ordinateur public, récupère son token et l’oublie en partant. Si quelqu’un d’autre tombe dessus, il peut continuer à accéder au compte sans limite de temps.
Votre token JWT doit toujours avoir une durée de validité. Une heure, une journée, selon votre application. Mais jamais illimitée.
Ne pas vérifier l’unicité de l’utilisateur à l’inscription
Sans cette vérification, vous risquez d’avoir plusieurs comptes avec le même email. Cela peut provoquer :
- des erreurs de connexion,
- des comportements incohérents,
- ou même des failles si un attaquant crée volontairement un “clone” pour vous perturber.
Une simple vérification suffit à éviter toute cette confusion.
Faire transiter le token en clair dans l’URL
Certaines personnes passent leurs tokens dans l’URL, comme ceci :
https://monapi.fr/dashboard?token=eyJhbGciOi...C’est une très mauvaise idée. L’URL peut être enregistrée dans l’historique, les logs serveur, ou même être exposée dans un lien partagé. Le token doit passer dans le header Authorization.
Adopter les bonnes pratiques : renforcer la sécurité de votre authentification Node.js
Une authentification basique peut fonctionner, mais pour construire un système réellement fiable, durable et digne d’une application professionnelle, quelques bonnes pratiques sont indispensables.
Utiliser dotenv pour isoler vos secrets
Votre clé secrète JWT ne doit jamais apparaître en clair dans votre code. Elle doit être stockée dans un fichier .env, qui lui-même ne doit jamais être versionné dans Git. Sans cela, vous prenez le risque de publier publiquement votre clé sur GitHub, ce qui revient à laisser votre maison ouverte en déposant les clés dans la boîte aux lettres.
dotenv vous permet de garder vos secrets loin des regards indiscrets, et d’avoir un code beaucoup plus propre. Cela permet aussi de changer facilement votre clé lors du déploiement sur un serveur distant.
Rendre vos tokens plus complets
Un token peut contenir beaucoup d’informations utiles, tant qu’elles ne sont pas sensibles. Par exemple :
- le rôle utilisateur,
- l’identifiant unique,
- une préférence de langue,
- ou même un état précis (compte validé, compte premium, etc.).
Ces données vous permettent ensuite de protéger certaines routes selon le rôle de l’utilisateur.
Ajouter un middleware pour limiter le nombre de tentatives
Il arrive qu’un attaquant tente des milliers de combinaisons de mot de passe pour accéder à un compte. Un système appelé “rate limiting” limite le nombre de tentatives successives depuis une même IP.
Si quelqu’un tente de se connecter cinquante fois en quinze secondes, vous pouvez être certain que ce n’est pas un utilisateur normal.
express-rate-limit est un module très pratique pour cela.
Vérifier systématiquement les données du formulaire
Avant d’enregistrer un utilisateur, vérifiez :
- que l’email ressemble à un email,
- que le mot de passe est assez long,
- que les champs ne sont pas vides,
- et que rien de suspect n’est envoyé.
La validation côté client ne suffit jamais. Elle est utile, mais les attaques contournent facilement le navigateur. Vous devez refaire ces vérifications côté serveur, dans votre code Node.js.
Organiser proprement votre architecture Node.js pour l’authentification
Pour un projet débutant, on peut tout mettre dans un seul fichier, mais très vite, cela devient illisible. Structurer votre projet proprement est essentiel pour comprendre votre code, le maintenir et le rendre évolutif.
Voici une architecture simple mais solide :
/project
app.js
/routes
auth.js
/middleware
auth.js
/controllers
authController.js
/models
userModel.js
.env
package.jsonPourquoi organiser autant ?
Parce qu’un projet mal rangé se transforme vite en cauchemar. On passe plus de temps à chercher où ajouter une fonction qu’à la coder réellement. Et lorsqu’il faut revenir deux mois plus tard, on a l’impression de lire du code écrit par un inconnu dans une langue étrangère.
Séparer par rôles (routes, middleware, modèles, contrôleurs) vous permet :
- d’identifier rapidement où se situe un problème,
- de réutiliser facilement des morceaux de code,
- et de rendre votre projet lisible même pour un autre développeur.
Un petit projet complet : l’authentification Node.js de A à Z
Pour mieux comprendre l’ensemble, construisons un mini projet complet et cohérent. Bien entendu, ce projet reste simplifié, mais il contient tout ce qui est nécessaire pour apprendre étape par étape.
Le modèle utilisateur
Dans models/userModel.js :
class UserModel {
constructor() {
this.users = [];
}
findByEmail(email) {
return this.users.find(user => user.email === email);
}
create(user) {
this.users.push(user);
return user;
}
}
module.exports = new UserModel();Dans un vrai projet, vous utiliseriez une base de données, mais ce modèle permet de comprendre un principe fondamental : séparer la logique de données du reste.
Le contrôleur d’authentification
Dans controllers/authController.js :
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const UserModel = require('../models/userModel');
exports.register = async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: 'Email et mot de passe requis.' });
}
const userExists = UserModel.findByEmail(email);
if (userExists) {
return res.status(400).json({ message: 'Cet email est déjà utilisé.' });
}
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = UserModel.create({
email,
password: hashedPassword
});
res.status(201).json({ message: 'Utilisateur créé.' });
};
exports.login = async (req, res) => {
const { email, password } = req.body;
const user = UserModel.findByEmail(email);
if (!user) {
return res.status(400).json({ message: 'Identifiants incorrects.' });
}
const valid = await bcrypt.compare(password, user.password);
if (!valid) {
return res.status(400).json({ message: 'Identifiants incorrects.' });
}
const token = jwt.sign(
{ email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
res.json({ message: 'Connexion réussie', token });
};Les routes
Dans routes/auth.js :
const express = require('express');
const router = express.Router();
const authController = require('../controllers/authController');
router.post('/register', authController.register);
router.post('/login', authController.login);
module.exports = router;Le middleware d’authentification
Dans middleware/auth.js :
const jwt = require('jsonwebtoken');
module.exports = function(req, res, next) {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ message: 'Token requis.' });
}
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch (e) {
res.status(401).json({ message: 'Token invalide.' });
}
};Le point d’entrée
Dans app.js :
require('dotenv').config();
const express = require('express');
const app = express();
const authRoutes = require('./routes/auth');
const authMiddleware = require('./middleware/auth');
app.use(express.json());
app.use('/auth', authRoutes);
app.get('/profil', authMiddleware, (req, res) => {
res.json({ email: req.user.email });
});
app.listen(3000, () => console.log('Serveur sur port 3000'));Vous avez maintenant un projet Node.js complet avec inscription, login, tokens, middleware et route protégée. Simple, propre et efficace.
Consolider vos bases pour aller plus loin
L’authentification en Node.js n’est jamais un simple détail technique, c’est une véritable porte d’entrée qui conditionne la sécurité et la fiabilité de toute votre application. Vous avez vu comment protéger les mots de passe grâce au hash, comment créer des tokens pour éviter les connexions répétées, comment structurer votre projet pour qu’il reste lisible, et comment mettre en place les bonnes pratiques indispensables pour ne pas laisser de brèches.
Vous disposez désormais de toutes les bases nécessaires pour comprendre ce qui se passe réellement dans les coulisses d’une authentification moderne. En prenant le temps d’explorer chaque notion, vous avez acquis bien plus que de simples bouts de code : vous avez appris à réfléchir comme un développeur qui prend soin de son application et de ses utilisateurs. C’est ce sens de la responsabilité, bien plus que la syntaxe, qui fera la différence sur vos futurs projets.
Si vous souhaitez continuer à progresser, vous avez devant vous plusieurs chemins possibles. Vous pourriez renforcer votre système avec un rôle administrateur, améliorer la sécurité en ajoutant un système de rafraîchissement de token, ou connecter votre API à une vraie base de données. Vous pourriez aussi intégrer ce module d’authentification dans un projet déjà existant, comme un tableau de bord ou un site complet. Quoi que vous décidiez, vous avez désormais entre les mains une fondation solide sur laquelle construire sans crainte.
Et surtout, retenez ceci : chaque fois que vous mettez en place une bonne pratique de sécurité, vous devenez un peu plus maître de votre environnement de développement. Node.js n’est plus un outil mystérieux, et l’authentification n’est plus ce monstre intimidant. Vous savez décortiquer, comprendre et protéger ce que vous construisez. C’est cette confiance, plus que tout, qui vous accompagnera dans vos projets les plus ambitieux.

Fondateur de l’agence Créa-troyes, affiliée France Num
Intervenant en Freelance.
Contactez-moi
