Limitador

Este é um middleware para o Fiber que é utilizado para limitar requisições repetitivas para APIs públicas e/ou endpoints (por exemplo, redefinição de senha). Também é útil para limitar a taxa de clientes de API, web crawlers ou outras tarefas que exigem limitação de taxa.

Nota: Este middleware utiliza nosso pacote Storage para suportar diversos bancos de dados por meio de uma interface unificada. A configuração padrão armazena dados na memória, e você pode consultar o exemplo abaixo para ver outros bancos de dados.

Nota: Por padrão, este módulo não compartilha estado com outros processos/servidores.

Assinatura

func New(config ...Config) fiber.Handler

Exemplo

Importe o pacote do middleware como parte do framework web Fiber:

import (
  "github.com/gofiber/fiber/v2"
  "github.com/gofiber/fiber/v2/middleware/limiter"
)

Depois de criar o aplicativo Fiber, você pode usar as seguintes opções:

// Inicialize com a configuração padrão
app.Use(limiter.New())


// Ou estenda com configuração 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: myCustomStorage{},
}))

Janela Deslizante

Você pode habilitar o algoritmo da janela deslizante em vez de usar o algoritmo de janela fixa padrão.

A configuração de exemplo é a seguinte:

app.Use(limiter.New(limiter.Config{
    Max:            20,
    Expiration:     30 * time.Second,
    LimiterMiddleware: limiter.SlidingWindow{},
}))

Isso significa que cada janela levará em conta a janela anterior (se houver). A fórmula para a taxa fornecida é:

pesoDaJanelaAnterior = quantidade de requisições da janela anterior * (quandoNovaJanela / Expiration)
taxa = pesoDaJanelaAnterior + quantidade de requisições da janela atual.

Configuração

Propriedade Tipo Descrição Padrão
Next func(*fiber.Ctx) bool Next define uma função para pular este middleware quando retornar verdadeiro. nil
Max int O número máximo de conexões dentro de Expiration segundos, retornando uma resposta 429 se excedido. 5
KeyGenerator func(*fiber.Ctx) string KeyGenerator permite gerar chaves personalizadas, usando por padrão c.IP(). Função usando c.IP() como valor padrão
Expiration time.Duration Expiration é o tempo para manter registros de requisições na memória. 1 * time.Minute
LimitReached fiber.Handler Chamado quando o limite é atingido. Função enviando uma resposta 429
SkipFailedRequests bool Se verdadeiro, não contar requisições com StatusCode >= 400. false
SkipSuccessfulRequests bool Se verdadeiro, não contar requisições com StatusCode < 400. false
Storage fiber.Storage Armazenar usado para armazenar o estado do middleware. Armazenamento na memória apenas para o processo atual
LimiterMiddleware LimiterHandler LimiterMiddleware é a estrutura que implementa o middleware limitador. Um novo limitador de taxa de janela fixa
Duração (Obsoleto) time.Duration Obsoleto: Usar Expiration em vez disso. -
Store (Obsoleto) fiber.Storage Obsoleto: Usar Storage em vez disso. -
Chave (Obsoleto) func(*fiber.Ctx) string Obsoleto: Usar KeyGenerator em vez disso. -

Nota: Se o armazenamento personalizado implementa a interface Storage, você pode usar o armazenamento personalizado - para mais informações e exemplos, consulte store.go.

Configuração Padrão

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{},
}

Armazenamento/Database Personalizado

Você pode usar qualquer método de armazenamento em nosso pacote de armazenamento.

armazenamento := sqlite3.New() // De github.com/gofiber/storage/sqlite3
app.Use(limiter.New(limiter.Config{
    Storage: armazenamento,
}))