Limitador
Este es un middleware para Fiber que se utiliza para limitar las solicitudes repetitivas a API públicas y/o puntos finales (por ejemplo, restablecimiento de contraseña). También es útil para limitar la velocidad de los clientes de API, los crawlers web u otras tareas que requieren limitación de velocidad.
Nota: Este middleware utiliza nuestro paquete Storage para admitir varias bases de datos a través de una interfaz unificada. La configuración predeterminada almacena datos en la memoria, y puede consultar el ejemplo a continuación para ver otras bases de datos.
Nota: De forma predeterminada, este módulo no comparte estado con otros procesos/servidores.
Firma
func New(config ...Config) fiber.Handler
Ejemplo
Importa el paquete de middleware como parte del framework web Fiber:
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/limiter"
)
Después de crear la aplicación Fiber, puedes utilizar las siguientes opciones:
// Inicializa con la configuración predeterminada
app.Use(limiter.New())
// O extiende con una configuración personalizada
app.Use(limiter.New(limiter.Config{
Next: func(c *fiber.Ctx) bool {
return c.IP() == "127.0.0.1"
},
Max: 20,
Expiration: 30 * time.Second,
KeyGenerator: func(c *fiber.Ctx) string {
return c.Get("x-forwarded-for")
},
LimitReached: func(c *fiber.Ctx) error {
return c.SendFile("./toofast.html")
},
Storage: miAlmacenamientoPersonalizado{},
}))
Ventana Deslizante
Puedes habilitar el algoritmo de ventana deslizante en lugar de usar el algoritmo de ventana fija estándar.
La configuración de ejemplo es la siguiente:
app.Use(limiter.New(limiter.Config{
Max: 20,
Expiration: 30 * time.Second,
LimiterMiddleware: limiter.SlidingWindow{},
}))
Esto significa que cada ventana tendrá en cuenta la ventana anterior (si la hay). La fórmula para la tasa dada es:
pesoDeLaVentanaAnterior = cantidad de solicitudes de la ventana anterior * (whenNewWindow / Expiration)
tasa = pesoDeLaVentanaAnterior + cantidad de solicitudes de la ventana actual.
Configuración
Propiedad | Tipo | Descripción | Predeterminado |
---|---|---|---|
Next | func(*fiber.Ctx) bool |
Next define una función para saltar este middleware cuando devuelve verdadero. | nil |
Max | int |
El número máximo de conexiones dentro de Expiration segundos, devolviendo una respuesta 429 si se excede. |
5 |
KeyGenerator | func(*fiber.Ctx) string |
KeyGenerator te permite generar claves personalizadas, utilizando c.IP() de forma predeterminada. | Función que utiliza c.IP() como valor predeterminado |
Expiration | time.Duration |
Expiration es el tiempo para mantener registros de solicitudes en la memoria. | 1 * time.Minute |
LimitReached | fiber.Handler |
Se llama cuando se alcanza el límite. | Función que envía una respuesta 429 |
SkipFailedRequests | bool |
Si es verdadero, no contar las solicitudes con StatusCode >= 400. | falso |
SkipSuccessfulRequests | bool |
Si es verdadero, no contar las solicitudes con StatusCode < 400. | falso |
Storage | fiber.Storage |
Almacén utilizado para almacenar el estado del middleware. | Almacenamiento en memoria solo para el proceso actual |
LimiterMiddleware | LimiterHandler |
LimiterMiddleware es la estructura que implementa el middleware limitador. | Un nuevo limitador de ventana fija |
Duración (Obsoleto) | time.Duration |
Obsoleto: Usa Expiration en su lugar. | - |
Almacenar (Obsoleto) | fiber.Storage |
Obsoleto: Usa Storage en su lugar. | - |
Clave (Obsoleto) | func(*fiber.Ctx) string |
Obsoleto: Usa KeyGenerator en su lugar. | - |
Nota: Si el almacenamiento personalizado implementa la interfaz
Storage
, puedes usar un almacenamiento personalizado; para obtener más información y ejemplos, consultastore.go
.
Configuración Predeterminada
var ConfigDefault = Config{
Max: 5,
Expiration: 1 * time.Minute,
KeyGenerator: func(c *fiber.Ctx) string {
return c.IP()
},
LimitReached: func(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusTooManyRequests)
},
SkipFailedRequests: false,
SkipSuccessfulRequests: false,
LimiterMiddleware: FixedWindow{},
}
Almacenamiento/Base de datos personalizado
Puedes utilizar cualquier método de almacenamiento en nuestro paquete de almacenamiento.
almacenamiento := sqlite3.New() // De github.com/gofiber/storage/sqlite3
app.Use(limiter.New(limiter.Config{
Storage: almacenamiento,
}))