Limiteur

Il s'agit d'un middleware pour Fiber qui est utilisé pour limiter les requêtes répétitives vers des API publiques et/ou des points d'accès (par exemple, la réinitialisation du mot de passe). Il est également utile pour limiter le taux des clients d'API, des robots d'indexation web, ou d'autres tâches nécessitant un contrôle de débit.

Remarque : Ce middleware utilise notre Storage package pour prendre en charge diverses bases de données via une interface unifiée. La configuration par défaut stocke les données en mémoire, et vous pouvez vous référer à l'exemple ci-dessous pour voir d'autres bases de données.

Remarque : Par défaut, ce module ne partage pas d'état avec d'autres processus/serveurs.

Signature

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

Exemple

Importez le package middleware dans le cadre du framework web Fiber :

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

Après avoir créé l'application Fiber, vous pouvez utiliser les options suivantes :

// Initialiser avec la configuration par défaut
app.Use(limiter.New())

// Ou étendre avec une configuration personnalisée
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("./tropvite.html")
    },
    Storage: myCustomStorage{},
}))

Fenêtre glissante

Vous pouvez activer l'algorithme de la fenêtre glissante au lieu d'utiliser l'algorithme de fenêtre fixe standard.

La configuration d'exemple est la suivante :

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

Cela signifie que chaque fenêtre prendra en compte la fenêtre précédente (le cas échéant). La formule pour le taux donné est la suivante :

poidsDeLaFenetrePrecedente = quantité de requêtes de la fenêtre précédente * (whenNewWindow / Expiration)
taux = poidsDeLaFenetrePrecedente + quantité de requêtes de la fenêtre actuelle.

Configuration

Propriété Type Description Par Défaut
Next func(*fiber.Ctx) bool Next définit une fonction pour sauter ce middleware lorsqu'elle retourne true. nil
Max int Le nombre maximum de connexions dans Expiration secondes, renvoyant une réponse 429 s'il est dépassé. 5
KeyGenerator func(*fiber.Ctx) string KeyGenerator vous permet de générer des clés personnalisées, en utilisant par défaut c.IP(). Fonction utilisant c.IP() comme valeur par défaut
Expiration time.Duration Expiration est le temps de conserver les enregistrements de requête en mémoire. 1 * time.Minute
LimitReached fiber.Handler Appelé lorsque la limite est atteinte. Fonction envoyant une réponse 429
SkipFailedRequests bool Si vrai, ne pas compter les requêtes avec StatusCode >= 400. false
SkipSuccessfulRequests bool Si vrai, ne pas compter les requêtes avec StatusCode < 400. false
Storage fiber.Storage Store utilisé pour stocker l'état du middleware. Stockage en mémoire uniquement pour le processus en cours
LimiterMiddleware LimiterHandler LimiterMiddleware est la structure implémentant le middleware limiteur. Un nouveau limiteur de débit à fenêtre fixe
Duration (Obsolète) time.Duration Obsolète : Utiliser Expiration à la place. -
Store (Obsolète) fiber.Storage Obsolète : Utiliser Storage à la place. -
Key (Obsolète) func(*fiber.Ctx) string Obsolète : Utiliser KeyGenerator à la place. -

Remarque : Si le stockage personnalisé implémente l'interface Storage, vous pouvez utiliser un stockage personnalisé - pour plus d'informations et d'exemples, veuillez vous référer à store.go.

Configuration par Défaut

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

Stockage personnalisé/Base de données

Vous pouvez utiliser n'importe quelle méthode de stockage dans notre package de stockage.

stockage := sqlite3.New() // Provenant de github.com/gofiber/storage/sqlite3
app.Use(limiter.New(limiter.Config{
    Stockage: stockage,
}))