TW3 — Technologies du Web 3

Middlewares

Fonctionnement du pipeline Express : next(), express.json, fichiers statiques, cors, morgan et authentification maison.

Un middleware est une fonction qui reçoit (req, res, next) et se place sur le trajet de la requête. Il peut lire, enrichir, bloquer ou laisser passer.

🧩 Anatomie

function chrono(req, res, next) {
  const debut = Date.now();
  res.on("finish", () => {
    console.log(`${req.method} ${req.originalUrl} — ${Date.now() - debut} ms`);
  });
  next(); // passe la main au maillon suivant
}

app.use(chrono);

Trois issues possibles pour un middleware :

  • appeler next() → la requête continue sa route ;
  • répondre (res.json(...), res.status(...).end()) → la chaîne s'arrête ;
  • appeler next(erreur) → saut direct vers le middleware d'erreur.

Oublier next() sans répondre laisse la requête suspendue : le client attend jusqu'au timeout. C'est le bug le plus fréquent des débutants sur Express.

🔢 Ordre d'exécution

Express empile les middlewares dans l'ordre où vous les enregistrez et les traverse de haut en bas.

app.use(express.json());        // 1. parse le corps JSON
app.use(morgan("dev"));         // 2. journalise
app.use("/api", apiRouter);     // 3. routes métier
app.use(gestionnaire404);       // 4. rien n'a répondu
app.use(gestionnaireErreurs);   // 5. quatre arguments

Placer express.json() après les routes rendrait req.body indéfini dans ces routes.

📦 Middlewares intégrés

MiddlewareRôle
express.json()Parse les corps application/json vers req.body
express.urlencoded({ extended: true })Parse les formulaires HTML
express.static("public")Sert les fichiers d'un dossier tel quel
import path from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

app.use(express.json({ limit: "1mb" }));
app.use(express.urlencoded()); // extended: true par défaut depuis Express 4.16
app.use(express.static(path.join(__dirname, "../public")));

Avec express.static, le fichier public/logo.png est accessible à /logo.png — le nom du dossier ne figure pas dans l'URL. Le chemin absolu via __dirname évite toute ambiguïté selon le répertoire de lancement.

🌍 Middlewares tiers

npm install cors morgan
import cors from "cors";
import morgan from "morgan";

app.use(morgan("dev"));
app.use(cors({ origin: "http://localhost:5173" }));
  • cors : ajoute les en-têtes qui autorisent un front hébergé sur une autre origine à appeler l'API. Sans lui, le navigateur bloque la réponse (le serveur, lui, a bien répondu).
  • morgan : journalise chaque requête avec méthode, URL, statut et durée.

🎯 Portée : global ou ciblé

app.use(chrono);                          // toutes les requêtes
app.use("/api/admin", verifierAdmin);     // uniquement sous /api/admin
app.get("/profil", authentifier, lireProfil); // une seule route

On peut aussi chaîner plusieurs middlewares sur une route : app.post("/articles", authentifier, valider, creerArticle).

🔐 Un middleware d'authentification maison

// middlewares/auth.js
const JETONS_VALIDES = new Map([["abc123", { id: 1, role: "admin" }]]);

export function authentifier(req, res, next) {
  const entete = req.headers.authorization; // "Bearer abc123"

  if (!entete?.startsWith("Bearer ")) {
    return res.status(401).json({ error: "Jeton manquant" });
  }

  const utilisateur = JETONS_VALIDES.get(entete.slice(7));
  if (!utilisateur) {
    return res.status(401).json({ error: "Jeton invalide" });
  }

  req.utilisateur = utilisateur; // enrichit la requête pour la suite
  next();
}

export function exigerRole(role) {
  return (req, res, next) => {
    if (req.utilisateur?.role !== role) {
      return res.status(403).json({ error: "Accès refusé" });
    }
    next();
  };
}

Usage :

app.delete("/api/articles/:id", authentifier, exigerRole("admin"), supprimerArticle);

exigerRole est une fabrique de middleware : elle renvoie une fonction, ce qui permet de la paramétrer.

401 signifie « je ne sais pas qui vous êtes », 403 « je sais qui vous êtes, mais c'est interdit ». Les confondre brouille le diagnostic côté client.

✅ Points clés

  • Signature (req, res, next) ; un middleware d'erreur en a quatre.
  • L'enregistrement décide de l'ordre d'exécution.
  • Un middleware peut enrichir req pour les maillons suivants.
  • Une fabrique de middleware permet de paramétrer un contrôle.

Express

Terminez le quiz du chapitre pour le marquer comme complété.

Tableau de bord

On this page