Aprende Laravel: Middleware

En el post de autenticación usaste el middleware auth para proteger rutas. Ahora vas a entender qué es y a escribir el tuyo. Un middleware es una capa por la que pasa cada petición HTTP antes (o después) de llegar a tu aplicación: puede inspeccionarla, modificarla o rechazarla. El ejemplo clásico es justamente auth: si no hay sesión, redirige al login; si la hay, deja pasar.
Cómo funciona: capas alrededor de la petición
Imagina la petición atravesando una serie de capas. Cada middleware decide si la deja avanzar (llamando a $next) o la corta (devolviendo una respuesta). Se crea con Artisan:
php artisan make:middleware EnsureTokenIsValidSe genera en app/Http/Middleware con el método handle:
<?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->input('token') !== 'mi-token-secreto') {
return redirect('/home');
}
return $next($request);
}
}La regla clave: return $next($request) pasa la petición a la siguiente capa; devolver una respuesta (como el redirect) la corta ahí mismo.
Antes o después de la aplicación
Un middleware puede actuar antes de que la app procese la petición, o después:
// ANTES: actúa y luego deja pasar
public function handle(Request $request, Closure $next): Response
{
// hacer algo con la petición...
return $next($request);
}
// DESPUÉS: deja pasar y luego actúa sobre la respuesta
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
// hacer algo con la respuesta...
return $response;
}Asignar middleware a rutas
Lo más común es aplicarlo a rutas concretas con ->middleware():
use App\Http\Middleware\EnsureTokenIsValid;
Route::get('/perfil', function () {
// ...
})->middleware(EnsureTokenIsValid::class);
// Varios a la vez:
Route::get('/', fn () => ...)->middleware([First::class, Second::class]);Grupos y alias
Laravel trae dos grupos predefinidos, web y api, que aplica automáticamente a routes/web.php y routes/api.php. El grupo web incluye sesión, cookies, errores compartidos y protección contra CSRF.
Además, varios middleware del framework tienen alias cortos que ya usaste sin saberlo:
| Alias | Middleware |
|---|---|
auth |
Authenticate |
guest |
RedirectIfAuthenticated |
verified |
EnsureEmailIsVerified |
can |
Authorize |
throttle |
ThrottleRequests |
signed |
ValidateSignature |
Puedes definir tus propios alias en bootstrap/app.php (en Laravel 13 la configuración de middleware vive ahí, ya no en Http/Kernel.php):
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'subscribed' => EnsureUserIsSubscribed::class,
]);
})Y registrarlo global (corre en cada petición) con append:
->withMiddleware(function (Middleware $middleware): void {
$middleware->append(EnsureTokenIsValid::class);
})Pasar parámetros al middleware
Un middleware puede recibir argumentos extra después de $next. El caso típico es verificar un rol:
public function handle(Request $request, Closure $next, string $role): Response
{
if (! $request->user()->hasRole($role)) {
// redirigir o abortar...
}
return $next($request);
}Se pasan en la ruta separando con : y comas:
Route::put('/post/{id}', function (string $id) {
// ...
})->middleware(EnsureUserHasRole::class.':editor');Siguiente Paso
Ya sabes filtrar peticiones. El último fundamento (y el que separa el código que aguanta del que no) es asegurarte de que todo funciona: los tests. Sigue con Aprende Laravel: Testing con Pest.
Preguntas Frecuentes
¿Qué es un middleware en Laravel?
Una capa que inspecciona o filtra cada petición HTTP antes (o después) de que llegue a tu aplicación. Puede dejarla pasar ($next($request)) o cortarla devolviendo una respuesta. El middleware auth es el ejemplo más conocido.
¿Cómo creo un middleware?
Con php artisan make:middleware NombreDelMiddleware. Se genera en app/Http/Middleware con un método handle(Request $request, Closure $next).
¿Dónde se registra el middleware en Laravel 13?
En bootstrap/app.php, dentro de ->withMiddleware(...). En versiones anteriores se hacía en app/Http/Kernel.php, que ya no existe en Laravel 11+.
¿Cómo aplico un middleware solo a algunas rutas?
Con ->middleware(MiMiddleware::class) en la ruta o el grupo. Para excluirlo de una ruta dentro de un grupo, usa ->withoutMiddleware([...]).
¿Puedo pasarle parámetros a un middleware?
Sí. Se declaran en handle() después de $next y se pasan en la ruta con MiMiddleware::class.':valor' (varios separados por comas).