Laravel Middleware in Dettaglio: Autenticazione, Rate Limiting e Middleware Personalizzati
Guida ai middleware Laravel con esempi pratici su guard di autenticazione, rate limiting con throttle, creazione di middleware personalizzati, attributi PHP in Laravel 13 e pattern avanzati per applicazioni in produzione.

Laravel middleware funge da strato di filtraggio tra le richieste HTTP in arrivo e la logica applicativa. Ogni richiesta passa attraverso una pipeline di classi middleware prima di raggiungere un controller, e ogni risposta attraversa la stessa pipeline al ritorno. La comprensione di questo meccanismo e essenziale per costruire applicazioni Laravel sicure e performanti.
I middleware intercettano le richieste HTTP prima che raggiungano le route. Laravel registra tutti i middleware in bootstrap/app.php utilizzando una API fluent. I middleware integrati gestiscono autenticazione, protezione CSRF, gestione delle sessioni e rate limiting.
Come funziona la pipeline middleware di Laravel
Il kernel HTTP di Laravel elabora ogni richiesta attraverso uno stack di middleware. Ogni middleware riceve la richiesta, esegue la propria logica e passa la richiesta al livello successivo tramite $next($request) oppure interrompe la pipeline restituendo direttamente una risposta.
Questa architettura segue il pattern Chain of Responsibility. I middleware possono agire prima che la richiesta raggiunga il controller (es. controlli di autenticazione), dopo la generazione della risposta (es. aggiunta di header), o in entrambe le fasi.
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesLog;
use SymfonyComponentHttpFoundationResponse;
class LogRequestTime
{
public function handle(Request $request, Closure $next): Response
{
$start = microtime(true); // Capture start time
$response = $next($request); // Pass to next middleware
$duration = microtime(true) - $start;
Log::info('Request completed', [
'url' => $request->url(),
'method' => $request->method(),
'duration' => round($duration * 1000, 2) . 'ms',
]);
return $response; // Return response up the stack
}
}Questo middleware avvolge la richiesta: registra il tempo di inizio prima dell'elaborazione e logga la durata dopo il ritorno della risposta. Questo pattern before/after e centrale nel funzionamento dei middleware.
Authentication Middleware: Protezione delle Route
Laravel include l'alias middleware auth, mappato su IlluminateAuthMiddlewareAuthenticate. Applicarlo a una route assicura che solo gli utenti autenticati possano accedervi. Gli utenti non autenticati ricevono una risposta 401 (API) o vengono reindirizzati alla pagina di login (web).
use AppHttpControllersDashboardController;
use AppHttpControllersProfileController;
// Single route protection
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
// Group protection for multiple routes
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::put('/profile', [ProfileController::class, 'update']);
Route::delete('/profile', [ProfileController::class, 'destroy']);
});Autenticazione Multi-Guard
Le applicazioni con piu tipologie di utenti (pannello admin, area clienti, API) beneficiano dell'autenticazione basata su guard. Il middleware auth accetta un parametro guard per specificare quale driver di autenticazione utilizzare.
// API routes use the 'sanctum' guard
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::apiResource('/orders', OrderController::class);
});
// routes/web.php
// Admin routes use a custom 'admin' guard
Route::middleware('auth:admin')->prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'index']);
Route::get('/users', [AdminController::class, 'users']);
});Il parametro guard dopo i due punti indica a Laravel quale configurazione di autenticazione verificare. Questo mantiene la logica di autenticazione pulita e separata tra le diverse aree dell'applicazione.
Il middleware guest e l'inverso di auth: permette il passaggio solo agli utenti non autenticati. Applicandolo alle route di login e registrazione si impedisce agli utenti gia autenticati di accedere a quelle pagine.
Rate Limiting con Throttle Middleware
Il rate limiting middleware di Laravel protegge le route dagli abusi utilizzando il middleware integrato throttle. La forma piu semplice accetta due parametri: il numero massimo di richieste e la finestra temporale in minuti.
// Allow 60 requests per minute per user
Route::middleware('throttle:60,1')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{post}', [PostController::class, 'show']);
});
// Stricter limit for write operations
Route::middleware(['auth:sanctum', 'throttle:10,1'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
});Rate Limiter Nominati per Controllo Avanzato
Definire rate limiter nominati nel AppServiceProvider offre un controllo granulare sui limiti in base al contesto utente. Questo approccio e piu flessibile dei parametri throttle inline. La documentazione ufficiale sul rate limiting offre opzioni aggiuntive.
use IlluminateCacheRateLimitingLimit;
use IlluminateSupportFacadesRateLimiter;
use IlluminateHttpRequest;
public function boot(): void
{
// API rate limiter with tiered access
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
if ($user?->hasSubscription('enterprise')) {
return Limit::perMinute(500)->by($user->id); // Enterprise: 500/min
}
if ($user) {
return Limit::perMinute(100)->by($user->id); // Authenticated: 100/min
}
return Limit::perMinute(20)->by($request->ip()); // Anonymous: 20/min
});
// Login limiter to prevent brute force
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by($request->ip()) // Key by IP address
->response(function () { // Custom exceeded response
return response()->json([
'message' => 'Too many login attempts. Try again in a minute.',
], 429);
});
});
}L'applicazione dei limiter nominati alle route usa la sintassi throttle:nome:
Route::middleware('throttle:api')->group(function () {
Route::apiResource('/posts', PostController::class);
});
// routes/web.php
Route::middleware('throttle:login')
->post('/login', [AuthController::class, 'login']);Il rate limiter a livelli sopra dimostra un pattern di produzione: gli utenti enterprise ottengono limiti piu alti, gli utenti autenticati limiti moderati, e le richieste anonime vengono limitate in modo aggressivo. Il metodo by() determina la chiave del rate limit, usando l'ID utente per gli utenti autenticati e l'indirizzo IP come fallback.
Pronto a superare i tuoi colloqui su Laravel?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
Costruire Middleware Personalizzati da Zero
La creazione di middleware personalizzati copre scenari che i middleware integrati non gestiscono. Il comando Artisan make:middleware genera una nuova classe con la struttura corretta.
php artisan make:middleware EnsureUserHasRoleMiddleware per Controllo Accessi Basato sui Ruoli
Un pattern comune per middleware personalizzati e l'autorizzazione basata sui ruoli a livello di route, accettando nomi di ruoli come parametri.
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationResponse;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
$user = $request->user();
if (! $user || ! $user->hasAnyRole($roles)) {
abort(403, 'Insufficient permissions.');
}
return $next($request);
}
}Il parametro variadic ...$roles permette di passare piu ruoli separati da virgola. Registrazione e utilizzo appaiono cosi:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => AppHttpMiddlewareEnsureUserHasRole::class,
]);
})
// routes/web.php
Route::middleware('role:admin')->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
});
// Multiple roles: admin OR editor can access
Route::middleware('role:admin,editor')->group(function () {
Route::resource('/articles', ArticleController::class);
});Middleware per Trasformazione delle Richieste
I middleware possono modificare la richiesta prima che raggiunga il controller. Un middleware per API JSON che impone header content type e trim degli input stringa:
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationResponse;
class ApiRequestSanitizer
{
public function handle(Request $request, Closure $next): Response
{
// Reject non-JSON requests on API routes
if (! $request->expectsJson() && $request->isMethod('POST')) {
return response()->json(
['error' => 'Content-Type must be application/json'],
415
);
}
// Trim all string inputs
$input = $request->all();
array_walk_recursive($input, function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
});
$request->merge($input);
return $next($request);
}
}Questo middleware gestisce due aspetti: valida il content type per le richieste POST e sanitizza tutti gli input stringa rimuovendo gli spazi.
Registrazione dei Middleware in bootstrap/app.php
Laravel centralizza tutta la registrazione dei middleware in bootstrap/app.php. Questo ha sostituito l'approccio precedente app/Http/Kernel.php che esisteva prima di Laravel 11. La stessa API fluent funziona in Laravel 12 e 13.
use IlluminateFoundationApplication;
use IlluminateFoundationConfigurationMiddleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Global middleware (runs on every request)
$middleware->append(
AppHttpMiddlewareLogRequestTime::class
);
// Add to the 'web' middleware group
$middleware->web(append: [
AppHttpMiddlewareTrackPageViews::class,
]);
// Add to the 'api' middleware group
$middleware->api(prepend: [
AppHttpMiddlewareApiRequestSanitizer::class,
]);
// Register aliases for route-level use
$middleware->alias([
'role' => AppHttpMiddlewareEnsureUserHasRole::class,
'subscribed' => AppHttpMiddlewareEnsureUserIsSubscribed::class,
]);
// Control execution order
$middleware->priority([
IlluminateSessionMiddlewareStartSession::class,
IlluminateAuthMiddlewareAuthenticate::class,
AppHttpMiddlewareEnsureUserHasRole::class,
]);
})
->create();L'array priority e importante quando piu middleware sono assegnati alla stessa route. Laravel li ordina secondo questa lista, assicurando che la sessione sia avviata prima dell'autenticazione, e l'autenticazione sia completata prima dei controlli sui ruoli.
I middleware vengono eseguiti nell'ordine di registrazione. Per i middleware a livello di route, l'array priority sovrascrive l'ordine predefinito. L'autenticazione deve sempre precedere i middleware di autorizzazione per evitare di verificare i ruoli su richieste non autenticate.
Attributi PHP per Middleware in Laravel 13
Laravel 13 ha introdotto l'attributo PHP #[Middleware] per dichiarare middleware direttamente su classi e metodi dei controller. Questo approccio mantiene la configurazione middleware co-localizzata con il codice che protegge, rendendo le regole di autorizzazione piu leggibili e manutenibili.
namespace AppHttpControllers;
use AppModelsComment;
use AppModelsPost;
use IlluminateRoutingAttributesControllersAuthorize;
use IlluminateRoutingAttributesControllersMiddleware;
#[Middleware('auth')]
class CommentController
{
#[Middleware('subscribed')]
#[Authorize('create', [Comment::class, 'post'])]
public function store(Post $post)
{
// Only authenticated, subscribed users who can create comments reach here
}
public function index(Post $post)
{
// Still requires auth (from class-level attribute)
return $post->comments;
}
}L'attributo #[Middleware('auth')] a livello di classe si applica a tutti i metodi. Gli attributi a livello di metodo si sommano: store() richiede sia auth che subscribed. L'attributo #[Authorize] si integra con il sistema di policy di Laravel, verificando i permessi prima dell'esecuzione del metodo.
Questo approccio basato su attributi e opzionale. La registrazione middleware nei file di route e in bootstrap/app.php rimane pienamente supportata. I team che preferiscono definizioni di route esplicite possono continuare a usare l'API fluent; i team che desiderano controller auto-documentanti possono adottare gli attributi.
Terminable Middleware per Task Post-Response
I terminable middleware eseguono logica dopo che la risposta e stata inviata al client. Questo e utile per logging, analytics o task di pulizia che non devono bloccare l'utente.
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesDB;
use SymfonyComponentHttpFoundationResponse;
class CollectAnalytics
{
public function handle(Request $request, Closure $next): Response
{
return $next($request); // Pass through without delay
}
public function terminate(Request $request, Response $response): void
{
// Runs after response is sent to client
DB::table('analytics')->insert([
'path' => $request->path(),
'method' => $request->method(),
'status_code' => $response->getStatusCode(),
'user_id' => $request->user()?->id,
'ip' => $request->ip(),
'created_at' => now(),
]);
}
}Il metodo terminate riceve sia la richiesta originale che la risposta finale. Il middleware deve essere registrato come singleton nel AppServiceProvider per assicurare che la stessa istanza gestisca sia handle() che terminate().
Pattern Middleware Pratici per la Produzione
Diversi pattern middleware appaiono costantemente nelle applicazioni Laravel in produzione.
Bypass della modalita manutenzione permette agli IP interni di accedere all'applicazione durante la manutenzione:
class MaintenanceBypass
{
private array $allowedIps = ['192.168.1.0/24', '10.0.0.1'];
public function handle(Request $request, Closure $next): Response
{
if (app()->isDownForMaintenance()) {
foreach ($this->allowedIps as $ip) {
if ($request->ip() === $ip) {
return $next($request);
}
}
}
return $next($request);
}
}Security header aggiungono HSTS, content security policy e altri header a ogni risposta:
class SecurityHeaders
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains'
);
return $response;
}
}Questi pattern dimostrano le due posizioni primarie dei middleware: prima della richiesta (il bypass manutenzione verifica l'IP e potenzialmente blocca) e dopo la risposta (i security header modificano la risposta in uscita).
Pronto a superare i tuoi colloqui su Laravel?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
Fonti
- Documentazione Laravel Middleware - Riferimento ufficiale per registrazione middleware, gruppi e parametri
- Note di rilascio Laravel 13 - Annuncio dell'attributo
#[Middleware]e miglioramenti aPreventRequestForgery - Documentazione Laravel Rate Limiting - Facade RateLimiter, limiter nominati e configurazione middleware throttle
Pattern Middleware Laravel per la Preparazione ai Colloqui
- I middleware Laravel operano come pipeline: ogni classe elabora la richiesta, agisce su di essa e la passa avanti o interrompe con una risposta
- Il middleware
authprotegge le route con autenticazione basata su guard, supportando piu tipi di utente tramite la sintassiauth:guard - Il rate limiting tramite middleware
throttlee definizioni nominaliRateLimiter::for()permette controllo accessi a livelli basato sul contesto utente - I middleware personalizzati gestiscono aspetti trasversali come verifica ruoli, sanitizzazione richieste e security header senza appesantire i controller
- Tutta la registrazione middleware avviene in
bootstrap/app.phpusando una API fluent, conpriorityche controlla l'ordine di esecuzione - L'attributo
#[Middleware]di Laravel 13 permette di dichiarare middleware direttamente sui controller, mantenendo le regole di autorizzazione co-localizzate con i gestori - I terminable middleware eseguono task post-response (analytics, logging) senza impattare la latenza percepita dall'utente
- I parametri middleware tramite la sintassi
:parammantengono le definizioni delle route espressive e le classi middleware riutilizzabili in contesti diversi
Inizia a praticare!
Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.
Sapresti trovare il bug in Laravel?
Uno snippet reale, un bug nascosto, un tentativo al giorno. Senza account per provare.

Scritto da
Anthony Fillion-MailletFondatore di SharpSkill
Sviluppatore fullstack da oltre 10 anni. Guida SharpSkill e risponde di tutto ciò che vi viene pubblicato.
Aggiornato il 21 settembre 2026
Tag
Condividi
Articoli correlati

Laravel 12 nel 2026: Nuove Funzionalità, Starter Kit e Domande per Colloqui
Laravel 12 introduce Starter Kit completamente riprogettati con React 19, Vue 3, Livewire 4 e WorkOS AuthKit. Una guida completa alle nuove funzionalità, al percorso di aggiornamento e alle domande chiave per i colloqui tecnici del 2026.

Laravel Solutions: Pattern Avanzati, Debugging e Domande da Colloquio 2026
Padroneggia le soluzioni Laravel con pattern architetturali avanzati, tecniche di debugging e preparazione ai colloqui. Service class, repository pattern, debugging con Telescope e domande frequenti per sviluppatori Laravel.

Laravel Events e Listeners 2026: Architettura Event-Driven e Domande da Colloquio
Guida completa a Laravel Events e Listeners nel 2026. Architettura Event-Driven, Observer Pattern, Broadcasting e le domande più frequenti nei colloqui tecnici con esempi di codice.