Un approfondimento sul facade RateLimiter di Laravel: dall’implementazione di rate limit personalizzati per utente, piano o indirizzo IP fino a configurazioni ad alta disponibilità con Redis.
Il rate limiting di Laravel è formato dalla classe Illuminate\Cache\RateLimiting\Limit e dal facade RateLimiter. Internamente memorizza contatori nel driver di cache (di default file o Redis) e tiene traccia del numero di richieste.Sulla richiesta ricevuta dal middleware throttle, viene eseguita la closure definita con RateLimiter::for(): se il limite è raggiunto, viene restituito 429 Too Many Requests.
Definire un limiter personalizzato in AppServiceProvider
Definisci le impostazioni di rate limit nel metodo boot() di App\Providers\AppServiceProvider.
<?phpnamespace App\Providers;use Illuminate\Cache\RateLimiting\Limit;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{ public function boot(): void { RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); }); }}
Il primo argomento di RateLimiter::for() è il nome del limiter, usato quando lo referenzi dal middleware throttle. La closure passata come secondo argomento deve restituire un’istanza Illuminate\Cache\RateLimiting\Limit.
Come funzionano gli header di risposta (X-RateLimit-*)
Il middleware throttle aggiunge automaticamente alle response gli header con le informazioni di limite.
Header
Descrizione
X-RateLimit-Limit
Numero di richieste consentite
X-RateLimit-Remaining
Numero di richieste rimanenti
Retry-After
Secondi prima della prossima richiesta possibile (solo su 429)
X-RateLimit-Reset
Timestamp UNIX di reset del limite
HTTP/1.1 429 Too Many RequestsX-RateLimit-Limit: 60X-RateLimit-Remaining: 0Retry-After: 45X-RateLimit-Reset: 1717000000Content-Type: application/json{ "message": "Too Many Requests."}
// numero di tentativi correnti$hits = RateLimiter::attempts($key);// secondi al prossimo reset$seconds = RateLimiter::availableIn($key);// verifica se il limite è stato raggiunto$tooMany = RateLimiter::tooManyAttempts($key, $maxAttempts = 5);// reset manuale del contatore (dopo logout, ecc.)RateLimiter::clear($key);
Così il middleware throttle viene mappato sulla classe ThrottleRequestsWithRedis e il conteggio avviene con precisione grazie alle operazioni atomiche di Redis.
Se usi throttleWithRedis(), assicurati che Redis sia sempre disponibile. In caso di errore di connessione a Redis, tutte le richieste potrebbero essere rifiutate.