Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🔐
Intermediaire 25 min Express

Authentification dans Express

Voici un tutoriel approfondi sur l'authentification dans Express :

Pourquoi Authentification dans Express ?

L'authentification est un élément essentiel de toute application web ou API, car elle permet de contrôler qui peut accéder aux ressources et à quoi. Dans le contexte quotidien du développement avec Express, l'authentification est cruciale pour protéger les données sensibles et pour assurer la sécurité des utilisateurs.

Un cas d'utilisation concret est une plateforme de gestion de tâches personnelle où les utilisateurs peuvent créer, modifier et supprimer des tâches. L'authentification permet aux utilisateurs de ne voir que leurs propres tâches et d'éviter qu'un utilisateur n'accède à des données qui ne lui appartiennent pas.

Prerequis

  • Connaissance de base de Node.js et Express
  • Familiarité avec les concepts de base de l'authentification (JWT, cookies, sessions)
  • Installation de Node.js v14 ou ultérieur
  • Installation de MongoDB (pour un projet réel)

Concepts fondamentaux

Middleware d'authentification

Un middleware est une fonction qui s'exécute entre la requête et la réponse dans le cycle de traitement d'une requête HTTP. Dans le cas de l'authentification, nous pouvons utiliser des middlewares pour vérifier les tokens JWT (JSON Web Tokens) ou les cookies pour authentifier les utilisateurs.

// middleware d'authentification avec JWT
const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (token == null) return res.sendStatus(401);

  jwt.verify(token, 'SECRET_KEY', (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

app.use(authenticateToken);

Gestion des sessions

Les sessions sont une autre méthode d'authentification qui permettent de stocker des informations sur l'état de l'utilisateur entre les requêtes.

// middleware de session avec express-session
const express = require('express');
const session = require('express-session');

const app = express();

app.use(session({
  secret: 'SECRET_KEY',
  resave: false,
  saveUninitialized: true,
}));

function isAuth(req, res, next) {
  if (req.session.authenticated) {
    next();
  } else {
    res.sendStatus(401);
  }
}

app.get('/dashboard', isAuth, (req, res) => {
  res.send('Bienvenue sur votre tableau de bord');
});

Mise en pratique : projet fil rouge

Pour ce tutoriel, nous allons construire un gestionnaire simple de tâches avec une authentification basée sur JWT.

Étape 1 : Initialisation du projet

mkdir task-manager
cd task-manager
npm init -y
npm install express jsonwebtoken body-parser mongoose cors

Étape 2 : Structure des fichiers

task-manager/
├── app.js
├── models/
│   └── Task.js
└── routes/
    ├── authRoutes.js
    └── taskRoutes.js

Étape 3 : Configuration de l'application

// app.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();
app.use(bodyParser.json());
app.use(cors());

require('./routes/authRoutes')(app);
require('./routes/taskRoutes')(app);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Étape 4 : Modèle de données

// models/Task.js
const mongoose = require('mongoose');

const taskSchema = new mongoose.Schema({
  title: String,
  description: String,
  completed: Boolean,
});

module.exports = mongoose.model('Task', taskSchema);

Étape 5 : Routes d'authentification

// routes/authRoutes.js
const express = require('express');
const jwt = require('jsonwebtoken');
const User = require('../models/User');

const router = express.Router();

router.post('/register', async (req, res) => {
  const { username, password } = req.body;
  try {
    const user = await User.create({ username, password });
    res.status(201).send('Utilisateur créé avec succès');
  } catch (error) {
    res.status(400).send(error.message);
  }
});

router.post('/login', async (req, res) => {
  const { username, password } = req.body;
  try {
    const user = await User.findOne({ username });
    if (!user || user.password !== password) {
      return res.status(401).send('Identifiants incorrects');
    }
    const token = jwt.sign({ id: user._id }, 'SECRET_KEY', { expiresIn: '1h' });
    res.send({ token });
  } catch (error) {
    res.status(500).send(error.message);
  }
});

module.exports = router;

Étape 6 : Routes de gestion des tâches

// routes/taskRoutes.js
const express = require('express');
const Task = require('../models/Task');

const router = express.Router();

router.get('/tasks', async (req, res) => {
  try {
    const tasks = await Task.find({});
    res.send(tasks);
  } catch (error) {
    res.status(500).send(error.message);
  }
});

router.post('/tasks', async (req, res) => {
  const task = new Task(req.body);
  try {
    await task.save();
    res.status(201).send(task);
  } catch (error) {
    res.status(400).send(error.message);
  }
});

module.exports = router;

Étape 7 : Commandes à exécuter

npm start

Erreurs frequentes et debugging

1. Token invalide

Code incorrect :

const token = 'invalid_token';
jwt.verify(token, 'SECRET_KEY', (err, user) => {
  if (err) console.log('Token invalide');
});

Code correct :

const token = 'invalid_token';
jwt.verify(token, 'SECRET_KEY', (err, user) => {
  if (err) return res.sendStatus(403);
});

2. Authentification non effectuée

Code incorrect :

app.get('/protected-route', (req, res) => {
  res.send('Accès autorisé');
});

Code correct :

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (token == null) return res.sendStatus(401);

  jwt.verify(token, 'SECRET_KEY', (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

app.get('/protected-route', authenticateToken, (req, res) => {
  res.send('Accès autorisé');
});

3. Problème avec les sessions

Code incorrect :

const session = require('express-session');

app.use(session({
  secret: 'SECRET_KEY',
  resave: false,
  saveUninitialized: true,
}));

function isAuth(req, res, next) {
  if (req.session.authenticated) {
    next();
  } else {
    res.sendStatus(401);
  }
}

app.get('/dashboard', isAuth, (req, res) => {
  res.send('Bienvenue sur votre tableau de bord');
});

Code correct :

const session = require('express-session');

app.use(session({
  secret: 'SECRET_KEY',
  resave: false,
  saveUninitialized: true,
}));

function isAuth(req, res, next) {
  if (req.session.authenticated) {
    next();
  } else {
    res.sendStatus(401);
  }
}

app.get('/dashboard', isAuth, (req, res) => {
  res.send('Bienvenue sur votre tableau de bord');
});

Pour aller plus loin

1. Utilisation d'un gestionnaire de mots de passe fort

La gestion des mots de passe est une partie essentielle de l'authentification. Considérez l'utilisation d'un gestionnaire de mots de passe fort comme bcrypt pour stocker les mots de passe en toute sécurité.

2. Gestion des tokens JWT

Les tokens JWT sont largement utilisés pour l'authentification car ils permettent une authentification sans cookies, ce qui est particulièrement utile dans des applications mobiles et front-ends réactifs.

3. Sécurité des sessions

Les sessions doivent être stockées de manière sécurisée. Considérez le stockage des sessions dans un système comme Redis pour améliorer la sécurité et l'évolutivité.

Défi pratique : Ajouter une fonctionnalité de réinitialisation de mot de passe

Ajoutez une fonctionnalité permettant aux utilisateurs de réinitialiser leur mot de passe. Cela impliquera la création d'un endpoint /forgot-password qui enverra un email avec un lien de réinitialisation, et le traitement du formulaire de réinitialisation.

// routes/authRoutes.js
router.post('/forgot-password', async (req, res) => {
  const { email } = req.body;
  try {
    // Génération d'un token pour la réinitialisation
    const token = jwt.sign({ email }, 'SECRET_KEY', { expiresIn: '1h' });
    // Envoi de l'email avec le lien de réinitialisation
    res.send('Email envoyé');
  } catch (error) {
    res.status(500).send(error.message);
  }
});

router.post('/reset-password/:token', async (req, res) => {
  const { password } = req.body;
  const token = req.params.token;
  try {
    jwt.verify(token, 'SECRET_KEY', async (err, decodedToken) => {
      if (err) return res.sendStatus(403);
      const user = await User.findOne({ email: decodedToken.email });
      user.password = password;
      await user.save();
      res.send('Mot de passe mis à jour');
    });
  } catch (error) {
    res.status(500).send(error.message);
  }
});

Ce tutoriel couvre les concepts fondamentaux de l'authentification dans Express, montre comment mettre en place une authentification basée sur JWT et MongoDB, et propose des pistes pour approfondir votre compréhension. N'oubliez pas de tester chaque étape et de corriger tout problème qui se présente durant le développement.

Besoin d'aide sur Express ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment installer Passport.js dans mon projet Express?
Pour installer Passport.js, utilisez la commande npm install passport.
Quelle est la différence entre les différentes stratégies d'authentification avec Passport.js?
Passport.js supporte plusieurs stratégies telles que le local (utilisant un nom d'utilisateur et un mot de passe), OAuth, JWT, etc. Chaque stratégie a ses propres avantages et est utilisée en fonction des besoins de l'application.
Comment protéger mes routes avec Passport.js?
Pour protéger vos routes, utilisez la méthode `passport.authenticate()` fournie par Passport.js. Vous pouvez spécifier le type de stratégie à utiliser (par exemple 'local') et passer des options appropriées.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.