Limiter

Questo è un middleware per Fiber che viene utilizzato per limitare le richieste ripetitive alle API e/o agli endpoint pubblici (ad esempio, reset della password). È anche utile per limitare il tasso di client API, web crawler o altre attività che richiedono un limite di velocità.

Nota: Questo middleware utilizza il nostro Storage package per supportare vari database attraverso un'interfaccia unificata. La configurazione predefinita memorizza i dati in memoria e puoi fare riferimento all'esempio di seguito per vedere altri database.

Nota: Per impostazione predefinita, questo modulo non condivide lo stato con altri processi/server.

Firma

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

Esempio

Importa il package middleware come parte del framework web Fiber:

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

Dopo aver creato l'applicazione Fiber, puoi utilizzare le seguenti opzioni:

// Inizializza con la configurazione predefinita
app.Use(limiter.New())

// O estendi con una configurazione personalizzata
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{},
}))

Sliding Window

Puoi abilitare l'algoritmo della finestra scorrevole invece di utilizzare l'algoritmo della finestra fissa standard.

La configurazione dell'esempio è la seguente:

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

Ciò significa che ogni finestra terrà conto della finestra precedente (se presente). La formula per il tasso dato è:

pesoFinestraPrecedente = numero di richieste della finestra precedente * (whenNewWindow / Expiration)
tasso = pesoFinestraPrecedente + numero di richieste della finestra attuale

Configurazione

Proprietà Tipo Descrizione Predefinito
Next func(*fiber.Ctx) bool Next definisce una funzione per saltare questo middleware quando restituisce true. nil
Max int Il numero massimo di connessioni entro Expiration secondi, restituendo una risposta 429 se superato. 5
KeyGenerator func(*fiber.Ctx) string KeyGenerator ti consente di generare chiavi personalizzate, utilizzando per impostazione predefinita c.IP(). Funzione che utilizza c.IP() come valore predefinito
Expiration time.Duration Expiration è il tempo per mantenere i record delle richieste in memoria. 1 * time.Minute
LimitReached fiber.Handler Chiamato quando il limite viene raggiunto. Funzione che invia una risposta 429
SkipFailedRequests bool Se vero, non conteggia le richieste con StatusCode >= 400. false
SkipSuccessfulRequests bool Se vero, non conteggia le richieste con StatusCode < 400. false
Storage fiber.Storage Store usato per memorizzare lo stato del middleware. Archiviazione in memoria solo per il processo corrente
LimiterMiddleware LimiterHandler LimiterMiddleware è la struttura che implementa il middleware del limite. Un nuovo limitatore di finestra fissa
Duration (Deprecato) time.Duration Deprecato: utilizza Expiration invece. -
Store (Deprecato) fiber.Storage Deprecato: utilizza Storage invece. -
Key (Deprecato) func(*fiber.Ctx) string Deprecato: utilizza KeyGenerator invece. -

Nota: Se lo storage personalizzato implementa l'interfaccia Storage, è possibile utilizzare uno storage personalizzato; per ulteriori informazioni ed esempi, si prega di fare riferimento a store.go.

Configurazione predefinita

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

Archiviazione personalizzata/Database

È possibile utilizzare qualsiasi metodo di archiviazione nel nostro pacchetto storage.

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