Skip to content

Développement API - Pierre Blarre

Authentification dans Node.js et MongoDB avec JWT et Cookies

Icône Présentation
1 / 1

L’authentification est un aspect crucial du développement web, garantissant que seuls les utilisateurs autorisés accèdent aux ressources protégées. Ce guide vous expliquera comment mettre en place une authentification sécurisée avec Node.js, MongoDB, JWT (JSON Web Token) et les cookies.

Ce tutoriel explique comment ajouter un système d’authentification basé sur JWT (JSON Web Token) à une application Node.js et MongoDB.

Il est très largement copié (traduit et corrigé) depuis https://medium.com/@codemaniac-sahil/authentication-in-nodejs-and-mongodb-using-jwt-and-cookies-d617bd98cdea

Prenez un temps pour lire et créez une nouvelle application pour tester l’authentification JWT.

Lorsque vous aurez terminé, vous pourrez ajouter des fonctionnalités à l’application pour gérer l’identification des joueurs.


📌 Qu’est-ce que l’authentification ?

L’authentification est le processus de vérification de l’identité d’un utilisateur ou d’un système. Son objectif est de s’assurer que l’entité tentant d’accéder à une ressource est bien celle qu’elle prétend être.

Authentification vs Autorisation

  • Authentification : Vérifie l’identité d’un utilisateur.
  • Autorisation : Définit les ressources ou actions qu’un utilisateur peut exécuter après son authentification.

📌 Qu’est-ce que JWT (JSON Web Token) ?

Le JWT est un format compact et sécurisé permettant d’échanger des informations entre deux parties. Il est souvent utilisé pour l’authentification et le transfert sécurisé d’informations.

🔑 Avantages de JWT :

  • Sans état : Pas besoin de stocker la session côté serveur.
  • Compact et efficace : Facilement transmissible dans une requête HTTP.
  • Sécurisé : Peut être signé et chiffré.
  • Polyvalent : Peut contenir des informations personnalisées sur l’utilisateur.

🚀 Mise en place du projet Node.js

1️⃣ Initialiser un projet Node.js

Dans un terminal, exécutez :

Terminal window
mkdir user-authentication
cd user-authentication
npm init -y

2️⃣ Installer les dépendances nécessaires

Terminal window
npm install express jsonwebtoken cookie-parser bcrypt cors body-parser dotenv mongoose

3️⃣ Créer le fichier index.js

const express = require("express");
const app = express();
const PORT = 8000;
app.listen(PORT, () => {
console.log(`Server is running on PORT ${PORT}`);
});

Lancez le serveur :

Terminal window
node index.js

Si tout fonctionne, vous verrez :

Server is running on PORT 8000

📌 Configuration de MongoDB

1️⃣ Connexion à la base de données

Créez un dossier database et un fichier db.js :

const mongoose = require("mongoose");
const env = require("dotenv");
env.config();
const dbconnection = async () => {
mongoose
.connect(process.env.MONGODB_URL)
.then(() => console.log("Database connected"))
.catch((err) => console.error(err));
};
module.exports = dbconnection;

2️⃣ Mise à jour de index.js

const express = require("express");
const Connection = require("./database/db");
const app = express();
const PORT = 8000;
Connection();
app.listen(PORT, () => {
console.log(`Server is running on PORT ${PORT}`);
});

3️⃣ Créez un fichier .env :

MONGODB_URL=mongodb://localhost:27017/{YOUR_DATABASE_NAME}

Testez la connexion avec :

Terminal window
npm start

Si tout fonctionne, vous verrez :

Server is running at port 8000
Database connected

📌 Création du modèle utilisateur

Dans le dossier database créez un dossier model et un fichier user.js :

const mongoose = require("mongoose");
const userSchema = mongoose.Schema({
name: String,
username: String,
email: String,
password: String,
});
const User = mongoose.model("user", userSchema);
module.exports = User;

🔑 Génération du JWT

Créez un dossier tokenGeneration et un fichier generateToken.js :

require("dotenv").config();
const jwt = require("jsonwebtoken");
module.exports.createSecretToken = (id) => {
return jwt.sign({ id }, process.env.TOKEN_KEY, {
expiresIn: 3 * 24 * 60 * 60, // Expiration : 3 jours
});
};

📌 Création des routes d’authentification

1️⃣ Inscription d’un utilisateur

Créez un dossier controller et un fichier signup.js :

const User = require("../database/model/user");
const { createSecretToken } = require("../tokenGeneration/generateToken");
const bcrypt = require("bcrypt");
const createUser = async (req, res) => {
try {
if (!(req.body.email && req.body.password && req.body.name && req.body.username)) {
return res.status(400).send("Tous les champs sont obligatoires.");
}
const oldUser = await User.findOne({ email: req.body.email });
if (oldUser) {
return res.status(409).send("L'utilisateur existe déjà.");
}
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const newUser = new User({
name: req.body.name,
username: req.body.username,
email: req.body.email,
password: hashedPassword,
});
const user = await newUser.save();
const token = createSecretToken(user._id);
res.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "None",
expires: new Date(Date.now() + 86400000),
});
res.json(user);
} catch (error) {
console.log("Erreur :", error);
}
};
module.exports = createUser;

2️⃣ Connexion d’un utilisateur

Créez un fichier login.js :

const User = require("../database/model/user");
const bcrypt = require("bcrypt");
const { createSecretToken } = require("../tokenGeneration/generateToken");
const login = async (req, res) => {
const { email, password } = req.body;
if (!(email && password)) {
return res.status(400).json({ message: "Tous les champs sont obligatoires." });
}
const user = await User.findOne({ email });
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(404).json({ message: "Identifiants invalides." });
}
const token = createSecretToken(user._id);
res.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "None",
expires: new Date(Date.now() + 86400000),
});
res.json({ token });
};
module.exports = login;

📌 Définition des routes

Créez un dossier routes et un fichier route.js :

const express = require("express");
const login = require("../controller/login");
const createUser = require("../controller/signup");
const router = express.Router();
router.post("/signup", createUser);
router.post("/login", login);
router.get("/logout", (req, res) => {
res.clearCookie("token");
res.json({ message: "Déconnexion réussie" });
});
module.exports = router;

Ajout des routes dans index.js

const express = require("express");
const app = express();
const Connection = require("./database/db");
const authRoute = require("./routes/route");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const PORT = 8000;
Connection();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use("/api", authRoute);
app.listen(PORT, () => {
console.log(`Server is running on PORT ${PORT}`);
});

📌 Configuration des variables d’environnement

Créez un fichier .env :

TOKEN_KEY=abc@123
FRONTEND_URL=http://localhost:3000
MONGODB_URL=mongodb://localhost:27017/{YOUR_DATABASE_NAME}

📌 Tester l’API

Vous pouvez télécharger cette collection Postman que j’ai préparée et l’importer dans votre installation de Postman pour tester les routes.

  • Signup Postman Body
  • Login Postman Body

✅ Conclusion

Ce guide vous a permis d’implémenter une authentification sécurisée en Node.js et MongoDB avec JWT et cookies. 🚀 Vous êtes maintenant prêt à sécuriser vos applications web !

Modification de l’application : Gestion des scores

Une fois l’authentification et le model des utilisateurs en place, vous pouvez ajouter des fonctionnalités pour gérer les scores des joueurs :

  1. Dans la partie serveur de l’application, ajouter des routes (GET, POST, PUT, DELETE) pour l’url /score qui permet de gérer les scores des joueurs, uniquement si le joueur est authentifié.
  2. Dans la partie client de l’application, ajouter les fonctionnalités suivantes pour :
    1. Identification du joueur
    2. Récupération du score du joueur
    3. Afficher le score record du joueur dans le canvas