Un Laravel middleware est une couche de filtrage qui s'exécute avant qu'une requête HTTP n'atteigne le cœur de votre application et avant que la réponse ne reparte vers le navigateur. Imaginez une série de portes placées entre la requête et votre controller : chaque porte inspecte la requête et peut l'arrêter, la modifier ou la transmettre à la porte suivante. L'authentification, la gestion de session, la protection CSRF ou la détection de langue se font presque toujours via un middleware.
Le rôle du middleware dans le cycle requête/réponse
Dans Laravel, chaque requête entrante traverse un « pipeline ». Ce pipeline fonctionne comme un oignon : la requête traverse chaque couche de l'extérieur vers l'intérieur jusqu'à atteindre le controller, et la réponse repart ensuite par les mêmes couches en sens inverse. Grâce à cela, un même middleware peut exécuter du code à la fois avant la requête et après la réponse.
- Code exécuté avant : vérifie la requête avant qu'elle n'atteigne le controller (par exemple : l'utilisateur est-il authentifié ?).
- Code exécuté après : agit une fois la réponse produite, comme ajouter un en-tête ou écrire un log.
L'ordre dans la chaîne est important. Le middleware qui démarre la session, par exemple, doit s'exécuter avant toute vérification qui dépend de cette session. Laravel définit un ordre par défaut cohérent, mais dans vos propres middlewares vous devez veiller à leur position dans la pile.
Comment fonctionne un middleware : la structure de base
Chaque middleware est une simple classe dotée d'une méthode handle. Cette méthode reçoit deux paramètres : la requête entrante $request et une closure nommée $next. Appeler $next($request) transmet la requête au maillon suivant de la chaîne.
public function handle(Request $request, Closure $next)
{
// Logique avant la requête
$response = $next($request);
// Logique après la réponse
return $response;
}
Tout ce que vous écrivez avant la ligne $next($request) s'exécute avant que la requête n'atteigne le controller ; tout ce qui se trouve après s'exécute pendant le retour de la réponse. Si vous ne voulez pas que la requête continue du tout (par exemple en cas d'accès refusé), il suffit de retourner une réponse sans appeler $next.
Écrire son propre middleware
La façon la plus pratique de créer un middleware est la commande Artisan :
php artisan make:middleware EnsureTokenIsValid
Cela génère le fichier app/Http/Middleware/EnsureTokenIsValid.php. Supposons que nous voulions rejeter toute requête ne contenant pas un token valide dans un en-tête donné :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureTokenIsValid
{
public function handle(Request $request, Closure $next): Response
{
if ($request->header('X-Api-Token') !== config('services.api.token')) {
abort(403, 'Token invalide.');
}
return $next($request);
}
}
Ici, si le token ne correspond pas, abort(403) coupe immédiatement la chaîne et la requête n'atteint jamais aucun controller. S'il correspond, le flux continue avec $next($request).
Enregistrer un middleware (Laravel 11 et 12)
Depuis Laravel 11, l'enregistrement des middlewares est passé de l'ancien fichier app/Http/Kernel.php vers bootstrap/app.php. Il existe trois grandes méthodes :
- Middleware global : appliqué à chaque requête.
- Middleware de groupe : ajouté aux groupes de routes comme
webouapi. - Middleware avec alias : assigné à des routes individuelles via
->middleware('alias').
// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Définir un alias à utiliser sur des routes individuelles
$middleware->alias([
'token' => \App\Http\Middleware\EnsureTokenIsValid::class,
]);
// Ajouter au groupe web
$middleware->web(append: [
\App\Http\Middleware\SetLocale::class,
]);
})
->create();
Une fois l'alias défini, vous l'utilisez sur les routes ainsi :
Route::get('/dashboard', DashboardController::class)
->middleware('token');
Remarque : si vous êtes encore sur Laravel 10 ou une version antérieure, ces mêmes enregistrements se font dans les tableaux $middlewareAliases et $middlewareGroups du fichier app/Http/Kernel.php.
Middleware qui reçoit des paramètres
Un middleware peut aussi accepter des arguments supplémentaires. Les vérifications d'autorisation et de rôle intégrées à Laravel reposent exactement sur ce principe. Vous ajoutez les paramètres à la méthode handle après $next :
public function handle(Request $request, Closure $next, string $role): Response
{
if (! $request->user()?->hasRole($role)) {
abort(403);
}
return $next($request);
}
Sur la route, vous passez la valeur après deux-points :
Route::get('/admin', AdminController::class)
->middleware('role:editor');
Erreurs fréquentes
- Oublier de retourner
$next($request): si la méthode ne renvoie pas de réponse, vous obtenez une page blanche ou une erreur. Sauf sortie anticipée, écrivez toujoursreturn $next($request). - Mauvais ordre : si un traitement dépendant de la session s'exécute avant le middleware de session, vous obtenez des résultats inattendus.
- Charge trop lourde : le middleware s'exécute à chaque requête ; utilisez avec parcimonie les requêtes en base et les appels d'API externes, et mettez-les en cache si possible.
Questions fréquentes
Quelle est la différence entre un middleware et un controller ?
Le controller exécute la logique métier propre à une route donnée. Le middleware est une couche transversale qui applique un filtrage ou des contrôles généraux à la requête et se répète sur de nombreuses routes. Des tâches comme l'authentification relèvent du middleware, pas du controller.
Puis-je ajouter plusieurs middlewares à une même route ?
Oui. Vous passez un tableau comme ->middleware(['auth', 'token', 'role:editor']) ; ils sont ajoutés à la chaîne dans l'ordre où vous les écrivez.
Puis-je exclure un middleware global de certaines routes ?
La solution la plus propre consiste généralement à ajouter le middleware au groupe ou aux routes concernées via un alias, plutôt que de le rendre global. Vous contrôlez ainsi précisément où il s'exécute.
Vous voulez mettre en place correctement l'architecture middleware de votre projet Laravel ? De l'authentification à la détection multilingue, je peux vous aider à concevoir une couche middleware propre et testable. Contactez-moi.