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, consulta store.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,
}))