acelerador
La clase Throttler proporciona una forma muy sencilla de limitar la realización de una actividad a un determinado número de intentos. dentro de un período de tiempo determinado. Esto se utiliza con mayor frecuencia para limitar la velocidad de las API o restringir el número de intentos que un usuario puede realizar contra un formulario para ayudar a prevenir ataques de fuerza bruta. La clase en sí se puede utilizar. para cualquier cosa que necesite acelerar en función de acciones dentro de un intervalo de tiempo establecido.
Descripción general
El Throttler implementa una versión simplificada del Token Bucket<https://en.wikipedia.org/wiki/Token_bucket> _
algoritmo. Básicamente, esto trata cada acción que desea como un depósito. Cuando llamas al método check()
,
usted le dice qué tan grande es el depósito, cuántas fichas puede contener y el intervalo de tiempo. Cada llamada check()
utiliza
1 de los tokens disponibles, por defecto. Veamos un ejemplo para aclarar esto.
Digamos que queremos que ocurra una acción una vez por segundo. La primera llamada al Throttler sería similar a la siguiente. El primer parámetro es el nombre del depósito, el segundo parámetro, la cantidad de tokens que contiene el depósito y el tercero es la cantidad de tiempo que tarda el balde en volver a llenarse:
<?php
$throttler = \Config\Services::throttler();
$throttler->check($name, 60, MINUTE);
Aquí estamos usando una de las constantes globales por el momento, para hacerlo un poco más legible. Esto dice que el depósito permite 60 acciones por minuto, o 1 acción por segundo.
Digamos que un script de terceros intentaba acceder a una URL repetidamente. Al principio, podría utilizar los 60 de esos tokens en menos de un segundo. Sin embargo, después de eso, el Throttler solo permitiría una acción por segundo. potencialmente ralentizando las solicitudes lo suficiente como para que el ataque ya no valga la pena.
Nota
For the Throttler class to work, the Cache library must be set up to use a handler other than dummy. Para obtener el mejor rendimiento, se recomienda una caché en memoria, como Redis o Memcached.
Limitación de tasa
La clase Throttler no limita la velocidad ni solicita aceleración por sí sola, pero es la clave para hacer una obra. Un ejemplo Filtro se proporciona que implementa un límite de tasa muy simple en una solicitud por segundo por dirección IP. Aquí explicaremos cómo funciona y cómo puede configurarlo y comience a usarlo en su aplicación.
El código
Puedes crear tu propio filtro Throttler, en app/Filters/Throttle.php, en la línea de:
<?php
namespace App\Filters;
use Higgs\Filters\FilterInterface;
use Higgs\HTTP\RequestInterface;
use Higgs\HTTP\ResponseInterface;
use Config\Services;
class Throttle implements FilterInterface
{
/**
* This is a demo implementation of using the Throttler class
* to implement rate limiting for your application.
*
* @param array|null $arguments
*
* @return mixed
*/
public function before(RequestInterface $request, $arguments = null)
{
$throttler = Services::throttler();
// Restrict an IP address to no more than 1 request
// per second across the entire site.
if ($throttler->check(md5($request->getIPAddress()), 60, MINUTE) === false) {
return Services::response()->setStatusCode(429);
}
}
/**
* We don't have anything to do here.
*
* @param array|null $arguments
*
* @return mixed
*/
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// ...
}
}
Cuando se ejecuta, este método primero toma una instancia del acelerador. A continuación, utiliza la dirección IP como nombre del depósito, y establece cosas para limitarlas a una solicitud por segundo. Si el acelerador rechaza la verificación y devuelve falso, luego devolvemos una respuesta con el código de estado establecido en 429 - Demasiados intentos y la ejecución del script finaliza antes de que llegue al controlador. Este ejemplo acelerará en función de una única dirección IP en todas las solicitudes. realizados al sitio, no por página.
Aplicar el filtro
No necesariamente necesitamos limitar cada página del sitio. Para muchas aplicaciones web, esto tiene más sentido. para aplicarse solo a solicitudes POST, aunque es posible que las API deseen limitar cada solicitud realizada por un usuario. Con el fin de aplicar esto para las solicitudes entrantes, debe editar app/Config/Filters.php y primero agregar un alias al filtrar:
<?php
namespace Config;
use Higgs\Config\BaseConfig;
class Filters extends BaseConfig
{
public $aliases = [
// ...
'throttle' => \App\Filters\Throttle::class,
];
// ...
}
A continuación, lo asignamos a todas las solicitudes POST realizadas en el sitio:
<?php
namespace Config;
use Higgs\Config\BaseConfig;
class Filters extends BaseConfig
{
public $methods = [
'post' => ['throttle'],
];
// ...
}
Advertencia
If you use $methods
filters, you should disable Auto Routing (Legacy)
porque Enrutamiento automático (heredado) permite que cualquier método HTTP acceda a un controlador.
Acceder al controlador con un método inesperado podría pasar por alto el filtro.
Y eso es todo. Ahora todas las solicitudes POST realizadas en el sitio tendrán que tener una tarifa limitada.
Referencia de clase
- check(string $key, int $capacity, int $seconds[, int $cost = 1])
- Parámetros:
$key (
string
) – el nombre del depósito$capacidad (
int
) – la cantidad de tokens que contiene el depósito$segundos (
int
) – el número de segundos que tarda un depósito en llenarse por completo$cost (
int
) – La cantidad de tokens que se gastan en esta acción
- Devuelve:
verdadero si se puede realizar la acción, falso si no
- Tipo del valor devuelto:
booleano
Comprueba si quedan fichas dentro del depósito o si hay demasiadas. sido utilizado dentro del límite de tiempo asignado. Durante cada comprobación los tokens disponibles se reducen en $cost si tienen éxito.
- getTokentime()
- Devuelve:
el número de segundos hasta que otro token esté disponible.
- Tipo del valor devuelto:
entero
Después de ejecutar
check()
y devolver falso, se puede utilizar este método para determinar el tiempo hasta que un nuevo token esté disponible y la acción pueda ser intentó de nuevo. En este caso, el tiempo de espera mínimo obligatorio es de un segundo.
- remove(string $key) self
- Parámetros:
$key (
string
) – el nombre del depósito
- Devuelve:
$esto
- Tipo del valor devuelto:
yo
Elimina y reinicia el cubo. No fallará si el depósito no existe.