Prologo
Primi Passi
Architettura
Le Basi
- Routing
- Middleware
- Protezione da CSRF
- Controller
- Richieste
- Risposte
- Views
- Blade
- Vite
- URL
- Sessioni
- Validazione
- Errori
- Logging
Approfondimenti
- Artisan
- Broadcasting
- Cache
- Collezioni
- Concorrenza
- Contesto
- Contratti
- Eventi
- File System
- Helpers
- Client HTTP
- Localizzazione
- Notifiche
- Sviluppo di Package
- Processi
- Code
- Rate-limiting
- Stringhe
- Scheduling di Task
Sicurezza
Database
Eloquent ORM
Testing
Package
Rate-limiting
Introduzione
Laravel include un’astrazione semplice da usare per il rate limiting che, insieme alla cache dell’applicazione, fornisce un modo facile per limitare qualsiasi azione durante una finestra di tempo specificata.
Se sei interessato al rate limiting delle richieste HTTP in entrata, consulta la documentazione del middleware rate limiter.
Configurazione della Cache
Tipicamente, il rate limiter utilizza la cache predefinita dell’applicazione come definito dalla chiave default
nel file di configurazione cache
della tua applicazione. Tuttavia, puoi specificare quale driver di cache deve usare il rate limiter definendo una chiave limiter
nel file di configurazione cache
della tua applicazione:
'default' => env('CACHE_STORE', 'database'),
'limiter' => 'redis',
Uso Base
La facade Illuminate\Support\Facades\RateLimiter
può essere utilizzata per interagire con il rate limiter. Il metodo più semplice offerto dal rate limiter è il metodo attempt
, che limita il tasso di esecuzione di una determinata callback per un dato numero di secondi.
Il metodo attempt
restituisce false
quando la callback non ha tentativi rimanenti disponibili; altrimenti, il metodo attempt
restituirà il risultato della callback o true
. Il primo argomento accettato dal metodo attempt
è una "key" del rate limiter, che può essere qualsiasi stringa a tua scelta che rappresenta l’azione che viene limitata:
use Illuminate\Support\Facades\RateLimiter;
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// Send message...
}
);
if (! $executed) {
return 'Too many messages sent!';
}
Se necessario, puoi fornire un quarto argomento al metodo attempt
, che è il "decay rate", ovvero il numero di secondi prima che i tentativi disponibili vengano resettati. Ad esempio, possiamo modificare l’esempio sopra per permettere cinque tentativi ogni due minuti:
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perTwoMinutes = 5,
function() {
// Send message...
},
$decayRate = 120,
);
Incremento Manuale dei Tentativi
Se desideri interagire manualmente con il rate limiter, sono disponibili diverse altre metodologie. Ad esempio, puoi invocare il metodo tooManyAttempts
per determinare se una determinata chiave del rate limiter ha superato il numero massimo di tentativi consentiti per minuto:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
return 'Troppi tentativi!';
}
RateLimiter::increment('send-message:'.$user->id);
// Invia messaggio...
In alternativa, puoi utilizzare il metodo remaining
per recuperare il numero di tentativi rimanenti per una determinata chiave. Se una chiave ha tentativi rimanenti, puoi invocare il metodo increment
per aumentare il numero totale di tentativi:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
RateLimiter::increment('send-message:'.$user->id);
// Invia messaggio...
}
Se desideri incrementare il valore per una determinata chiave del rate limiter di più di uno, puoi fornire l’ammontare desiderato al metodo increment
:
RateLimiter::increment('send-message:'.$user->id, amount: 5);
Determinare la Disponibilità del Limiter
Quando una chiave non ha più tentativi disponibili, il metodo availableIn
restituisce il numero di secondi rimanenti prima che siano disponibili altri tentativi:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
$seconds = RateLimiter::availableIn('send-message:'.$user->id);
return 'Puoi riprovare tra '.$seconds.' secondi.';
}
RateLimiter::increment('send-message:'.$user->id);
// Invia messaggio...
Resettare i Tentativi
Puoi resettare il numero di tentativi per una specifica chiave del rate limiter usando il metodo clear
. Ad esempio, puoi resettare i tentativi quando un messaggio viene letto dal destinatario:
use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;
/**
* Segna il messaggio come letto.
*/
public function read(Message $message): Message
{
$message->markAsRead();
RateLimiter::clear('send-message:'.$message->user_id);
return $message;
}