es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Laravel: devolver bool desde el grupo de limitación personalizado de middleware de throttling.

Quiero implementar mis propias lógicas personalizadas en el grupo de middleware de rutas de mi aplicación Laravel.

¿Qué puedo usar por ahora con Laravel:

Route::middleware('throttle:10,1')->group(function () {
   Route::get('/test/throttle', function() {
      return response('OK', 200)->header('Content-Type', 'text/html');
   });
});

Así que, como se esperaba, devuelve la vista de código 429 por defecto como HttpResponseException.


Pero quiero anular el middleware de throttle y devolver sólo un valor (bool) de tooManyAttempts como argumento de la función:

Route::middleware('customthrottle:10,1')->group(function ($tooManyAttempts) {

Route::get('/test/throttle', function() {
      if ($tooManyAttempts) {
         return response("Mi página personalizada 'Demasiados intentos' sólo para esta ruta", 200)->header('Content-Type', 'text/html');
      } else {
         return response('Todo está bien, jeje', 200)->header('Content-Type', 'text/html');
      }
   });
});

Leí este artículo, pero no sé cómo anularlo de tal manera que pueda pasar algún valor como argumento de función. Puede ser (bool) valor $tooManyAttempts o al menos valor (int) $maxAttempts.


¿Qué método debo anular exactamente y de qué manera para hacer eso?
(vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php)

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para implementar lógica personalizada en un grupo de rutas de middleware en Laravel, es posible sobrescribir el método handle del middleware ThrottleRequests. Este método se encarga de manejar las solicitudes entrantes y aplicar la lógica de límite de velocidad en función de los parámetros proporcionados.

    Para sobrescribir este método, se debe crear un nuevo middleware y extender el middleware ThrottleRequests. Luego, sobrescribir el método handle, como se muestra a continuación:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Exceptions\HttpResponseException;
    use Illuminate\Http\Exceptions\ThrottleRequestsException;
    use Illuminate\Routing\Middleware\ThrottleRequests;
    
    class CustomThrottle extends ThrottleRequests
    {
        public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1, $prefix = '')
        {
            $tooManyAttempts = $this->limiter->tooManyAttempts(
                $this->resolveRequestSignature($request),
                $this->resolveMaxAttempts($request, $maxAttempts)
            );
    
            if ($tooManyAttempts) {
                return $next($request, true);
            }
    
            return parent::handle($request, $next, $maxAttempts, $decayMinutes, $prefix);
        }
    
        protected function buildException($request, $key, $maxAttempts, $responseCallback = null)
        {
            // Lógica personalizada de manejo de excepciones aquí
            return new ThrottleRequestsException('Demasiados intentos.', null, []);
        }
    }
    

    En el código anterior, primero se verifica si la solicitud ha superado el límite máximo de intentos. Si es así, se llama al cierre $next con el indicador $tooManyAttempts establecido en true. De lo contrario, se llama al método handle del padre como de costumbre.

    También se sobrescribe el método buildException para proporcionar una lógica personalizada de manejo de excepciones. Aquí, es posible devolver su propia instancia de ThrottleRequestsException con cualquier encabezado o mensaje personalizado según sea necesario.

    Para usar este middleware en su grupo de rutas, simplemente cambie el nombre del middleware de 'throttle' a 'customthrottle':

    Route::middleware('customthrottle:10,1')->group(function ($tooManyAttempts) {
        Route::get('/test/throttle', function() use ($tooManyAttempts) {
            if ($tooManyAttempts) {
                return response("Mi página personalizada 'Demasiados intentos' solo para esta ruta", 200)->header('Content-Type', 'text/html');
            } else {
                return response('Puedes continuar, ja-ja', 200)->header('Content-Type', 'text/html');
            }
        });
    });
    

    Note que también agregamos $tooManyAttempts como parámetro a la clausura dentro del grupo de rutas, que recibirá el indicador establecido en nuestro middleware personalizado.

Comments are closed.