1. Profundizando
  2. Limitación de Tasa

Introducción

Laravel incluye una abstracción simple de uso para limitar la tasa que, junto con la caché de tu aplicación, proporciona una forma fácil de limitar cualquier acción durante un período de tiempo especificado.

Nota Si estás interesado en limitar la tasa de solicitudes HTTP entrantes, por favor consulta la documentación del middleware de limitación de tasa.

Configuración de Caché

Normalmente, el limitador de tasa utiliza la caché predeterminada de tu aplicación según lo definido por la clave default en el archivo de configuración de caché de tu aplicación. Sin embargo, puedes especificar qué controlador de caché debería usar el limitador de tasa definiendo una clave limiter en el archivo de configuración de caché de tu aplicación:

'default' => 'memcached',
 
'limiter' => 'redis',

Uso Básico

El facade Illuminate\Support\Facades\RateLimiter se puede utilizar para interactuar con el limitador de tasa. El método más simple ofrecido por el limitador de tasa es el método attempt, que limita la tasa de llamada a una devolución de llamada dada durante un número determinado de segundos.

El método attempt devuelve false cuando la devolución de llamada no tiene intentos disponibles restantes; de lo contrario, el método attempt devolverá el resultado de la devolución de llamada o true. El primer argumento aceptado por el método attempt es una "clave" de limitador de tasa, que puede ser cualquier cadena de tu elección que represente la acción que se está limitando:

use Illuminate\Support\Facades\RateLimiter;
 
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// Enviar mensaje...
}
);
 
if (! $executed) {
return 'modify_10x/rate-limiting.return_text_43';
}

Si es necesario, puedes proporcionar un cuarto argumento al método attempt, que es la "tasa de decaimiento", o el número de segundos hasta que los intentos disponibles se restablezcan. Por ejemplo, podemos modificar el ejemplo anterior para permitir cinco intentos cada dos minutos:

$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perTwoMinutes = 5,
function() {
// Enviar mensaje...
},
$decayRate = 120,
);

Incrementar Intentos Manualmente

Si deseas interactuar manualmente con el limitador de tasa, hay disponibles varios otros métodos. Por ejemplo, puedes invocar el método tooManyAttempts para determinar si una clave de limitador de tasa dada ha excedido su número máximo de intentos permitidos por minuto:

use Illuminate\Support\Facades\RateLimiter;
 
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
return 'modify_10x/rate-limiting.return_text_65';
}
 
RateLimiter::hit('send-message:'.$user->id);
 
// Enviar mensaje...

Alternativamente, puedes usar el método remaining para recuperar el número de intentos restantes para una clave dada. Si una clave dada tiene reintentos restantes, puedes invocar el método hit para incrementar el número total de intentos:

use Illuminate\Support\Facades\RateLimiter;
 
if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
RateLimiter::hit('send-message:'.$user->id);
 
// Enviar mensaje...
}

Determinar Disponibilidad del Limitador

Cuando una clave no tiene más intentos, el método availableIn devuelve el número de segundos restantes hasta que haya más intentos disponibles:

use Illuminate\Support\Facades\RateLimiter;
 
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
$seconds = RateLimiter::availableIn('send-message:'.$user->id);
 
return 'modify_10x/rate-limiting.return_text_92';
}
 
RateLimiter::hit('send-message:'.$user->id);
 
// Enviar mensaje...

Borrar Intentos

Puedes restablecer el número de intentos para una clave de limitador de tasa dada usando el método clear. Por ejemplo, puedes restablecer el número de intentos cuando un mensaje dado es leído por el receptor:

use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Marcar el mensaje como leído.
*/
public function read(Message $message): Message
{
$message->markAsRead();
 
RateLimiter::clear('send-message:'.$message->user_id);
 
return $message;
}