ExpressJS: Middleware

Un middleware est une fonction qui intercepte les requêtes HTTP reçue permettant de :
  1. Modifier la requête (req) reçu avant d'exécuter une fonction du controller
  2. Exécuter des vérifications (utilisateur connecté ...) avant d'exécuter une fonction du controller
  3. Exécuter des vérifications sur les attributs de la request reçue
  4. Sauvegarder des logs de navigation

routage.js

/*importer la bilbiothèque exprejss*/
const express = require('express')
/*Créer une instance du module Router */
let app = express.Router()


/*un middleware Globale qui intercepte toutes les route avec toutes méthodes http
Get /hello
Post /a/b/x
....
*/
app.use('/', function(req, res, next){
 //toujour exéuté
  console.log("save log"+req )
  /*on peut faire des vérification sur l'objet req de type request:
  if(req.body...) res.send("Erreur")
  ....
  */
  //Si la vérification passe on laisse passé la requête vers le mapping route/methodeHTTP
   next();
});


//example route
app.get('/okBien', function(req, res){
   res.send('Traitment Faite aprés Le middleware');
});


/*1.Middleware : On peut spécifier aussi sur quelle route on active un middleware */
app.use('/user/:id', (req, res, next) => {
    console.log('Request Type:', req.method)
    next()
  })

/*2.la route intercepté */
  app.get('/user/:id', (req, res, next) => {
    res.send('USER')
  })


  /*On peut appliquer une série de middleware sur la meme route */
  app.use('/test/:id', (req, res, next) => {
    console.log('Request URL:', req.originalUrl)
    next()
  }, (req, res, next) => {
    console.log('Request Type:', req.method)
    next()
  })



 
  //un middleware Globale sera active sur toutes routes et les methodes http
  app.use((req, res, next) => {
    console.log('Time:', Date.now())
    next()
  })



//la méthode http get mappé avec la route /
app.get('/', function (req, res) {
res.send('Afficher la listes des tests');
});



//.....

//n'importe quelle autre route
app.get('*', function(req, res){
   res.send('404 route not found');
});

module.exports = app

module.exports = app

L'objet req

req est un objet de type httpRequest contenant les attributs suivants :
  1. req.baseUrl:la route qui envoie la requête
  2. req.body :les données envoyées reçues (formulaire)
  3. eq.params: Les données envoyées via les URL
  4. req.cookies : les cookies envoyés
  5. req.ip : l'adresse IP du client
  6. ....

Exemple2:Connexion

server.js

const express = require('express');
const app = express();

// Middleware pour simuler l'authentification
const authenticateUser = (req, res, next) => {
  const isAuthenticated = true; // Remplacez ceci par votre mécanisme réel d'authentification

  if (isAuthenticated) {
    // L'utilisateur est authentifié, continuez vers la route suivante
    next();
  } else {
    // L'utilisateur n'est pas authentifié, redirigez-le vers une page de connexion
    res.redirect('/login');
  }
};

// Middleware pour enregistrer les informations de la requête dans la console
const logRequest = (req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  next();
};

// Utilisation des middlewares pour toutes les routes
app.use(logRequest);

// Route principale
app.get('/', (req, res) => {
  res.send('Bienvenue sur la page d\'accueil !');
});

// Route pour la page de profil (l'utilisateur doit être authentifié)
app.get('/profile', authenticateUser, (req, res) => {
  res.send('Bienvenue sur votre page de profil !');
});

// Route pour la page de connexion
app.get('/login', (req, res) => {
  res.send('Veuillez vous connecter pour accéder à votre profil.');
});

// Démarrage du serveur sur le port 3000
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Serveur Express en cours d'exécution sur le port ${PORT}`);
});

Exemple3:afficher le log de chaque Request

server.js

const express = require('express');
const app = express();

// Middleware pour logger les informations de la requête
const requestLoggerMiddleware = (req, res, next) => {
  // Enregistre le début du traitement de la requête
  const startTime = Date.now();
  
  // Enregistre des informations sur la requête dans la console
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  
  // Passe à la route suivante dans la pile de middleware
  next();
  
  // Enregistre la fin du traitement de la requête et calcule la durée
  const endTime = Date.now();
  const duration = endTime - startTime;
  
  // Enregistre des informations sur la durée de la requête dans la console
  console.log(`[${new Date().toISOString()}] Temps de traitement : ${duration} ms`);
};

// Utilise le middleware pour toutes les routes
app.use(requestLoggerMiddleware);

// Route principale
app.get('/', (req, res) => {
  // Envoie une réponse avec le corps "Hello, World!"
  res.send('Hello, World!');
});

// Démarrage du serveur sur le port 3000
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Serveur Express en cours d'exécution sur le port ${PORT}`);
});

Créer un middleware :module

On peut créer un module contenant un ensemebles de fonctions qui joue le role d'un middleware
Exemple1
validateDataMiddleware.js

// validateDataMiddleware.js
const validateDataMiddleware = (req, res, next) => {
  const { title, content } = req.body;

  // Vérifie si les champs "title" et "content" sont présents dans le corps de la requête
  if (!title || !content) {
    // Si l'un des champs est manquant, renvoie une réponse d'erreur
    return res.status(400).send('Les champs "title" et "content" sont requis.');
  }

  // Si les données sont valides, passe à la route suivante
  next();
};

module.exports = validateDataMiddleware;
server.js

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// Importe le middleware de validation des données
const validateDataMiddleware = require('./validateDataMiddleware');

// Utilise le middleware pour parser le corps des requêtes en JSON
app.use(bodyParser.json());

// Utilise le middleware de validation des données pour une route spécifique
app.post('/addArticle', validateDataMiddleware, (req, res) => {
  // Si les données sont valides, ajoutez l'article (simulé) et renvoyez une réponse
  const { title, content } = req.body;
  const article = { title, content };
  // Ici, vous pourriez enregistrer l'article dans une base de données, mais nous allons le simuler
  res.send(`Article ajouté : ${JSON.stringify(article)}`);
});

// Démarrage du serveur sur le port 3000
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Serveur Express en cours d'exécution sur le port ${PORT}`);
});

 
Exemple2
un middleware pour gérer l'authentification des utilisateurs. Le middleware va vérifier la présence d'un jeton d'authentification dans l'en-tête de la requête.
authMiddleware.js

 // authMiddleware.js
const authMiddleware = (req, res, next) => {
  const authToken = req.headers.authorization;

  // Vérifie si le jeton d'authentification est présent dans l'en-tête
  if (!authToken) {
    // Si le jeton n'est pas présent, renvoie une réponse d'erreur
    return res.status(401).send('Accès non autorisé. Jeton d\'authentification manquant.');
  }

  // Ici, vous pourriez implémenter une vérification réelle du jeton (décodez, validez, etc.)
  // Pour l'exemple, on suppose simplement que le jeton est valide
  // Dans un scénario réel, utilisez une bibliothèque comme jsonwebtoken pour gérer cela

  // Si le jeton est valide, passe à la route suivante
  next();
};

module.exports = authMiddleware;
 
server.js

const express = require('express');
const app = express();

// Importe le middleware d'authentification
const authMiddleware = require('./authMiddleware');

// Utilise le middleware d'authentification pour toutes les routes nécessitant une authentification
app.use(['/secureRoute1', '/secureRoute2'], authMiddleware);

// Route accessible à tous
app.get('/', (req, res) => {
  res.send('Bienvenue sur la page d\'accueil !');
});

// Route nécessitant une authentification
app.get('/secureRoute1', (req, res) => {
  res.send('Contenu de la route sécurisée 1.');
});

// Une autre route nécessitant une authentification
app.get('/secureRoute2', (req, res) => {
  res.send('Contenu de la route sécurisée 2.');
});

// Démarrage du serveur sur le port 3000
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Serveur Express en cours d'exécution sur le port ${PORT}`);
}); 
Exemple3

Middlewares.js

//intercepter toutes les requêtes puis vérifier si les données envoyées sont codées sous forme de json
module.exports.fonction1 = () => {
    return (req, res, next) => {
      if (req.headers['content-type'] !== 'application/json') {
          res.status(400).send('Server requires application/json')
      } else {
        next()
      }
    }
  }
  //...
 

Serveur.js

//importer expressjs
var express = require('express');
 var app = express();


//tester la connexion
const middlewares = require('./Middlewares');
app.get('/testJson', middlewares.fonction1(), (req, res, next) => {
  res.send('Bien Reçu');
   
});


//les routes
const test = require('./routage')
app.use('/tests',test)

//démarer le serveur sur le port 8081
app.listen(8081, function () {
console.log('Écoute du port 8081');
});

morgan Middleware

c'est quoi un middleware qui pemet d'intercepter les requetes http et générer un log pour toutes les routes et les apis comsomer

Installer morgan

npm install morgan --save

Serveur.js

//importer expressjs
var express = require('express');
var app = express();


/*Importer le module*/
const morgan = require("morgan")
// appliquer le Middleware
app.use(morgan("common"))


//les routes
const test = require('./routage')
app.use('/tests',test)

//démarer le serveur sur le port 8081
app.listen(8081, function () {
console.log('Écoute du port 8081');
});

Middleware Helmet

helmet est un middleware qui permet de protéger une application ExpressJS contre les vulnérabilité connue de ExpressJS en cachant des informations du header

Installer Helmet

npm install helmet --save

Serveur.js

//importer expressjs
var express = require('express');
var app = express();

// Morgan Middlewares
const helmet = require("helmet");
app.use(helmet());



/*Importer le module*/
const morgan = require("morgan")
// appliquer le Middleware
app.use(morgan("common"))


//les routes
const test = require('./routage')
app.use('/tests',test)

//démarer le serveur sur le port 8081
app.listen(8081, function () {
console.log('Écoute du port 8081');
});

Middleware Rate Limit

le middleware Rate Limit permet de limiter le nombre de requête pas adresse IP afin de sécuriser l'application entre les attacks DDos attack

Installer Helmet

npm install express-rate-limit --save

Serveur.js

//importer expressjs
var express = require('express');
 var app = express();


//express-rate-limit Middleware
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({
    windowMs: 1 * 60 * 1000, // durant chaque minute une adresse ip poura appeler (max) http requête dans le serveur
    max: 5, // 5 requêtes http pour chaque windowMs
    message: "Plusieurs requête from this ip"

  });
/*On peut appliquer un limiter sur toutes les requêtes http*/
app.use(limiter);

/*On peut appliquer un limiter seulement sur une racine des routes*/
app.use("/apis/", limiter);



// Morgan Middleware
const helmet = require("helmet");
app.use(helmet());



/*Importer le module*/
const morgan = require("morgan")
// appliquer le Middleware
app.use(morgan("common"))


//les routes
const test = require('./routage')
app.use('/tests',test)

//démarer le serveur sur le port 8081
app.listen(8081, function () {
console.log('Écoute du port 8081');
});










Cours et TPs