Le rate limiting est la technique défensive qui limite le nombre de requêtes qu'un client (humain, machine, IP) peut envoyer à un service dans une fenêtre temporelle donnée. Codifié par OWASP API Security Top 10 2023 sous l'identifiant API4:2023 (Unrestricted Resource Consumption), c'est l'une des défenses les plus fondamentales et les plus fréquemment mal implémentées en 2026. Sans rate limiting effectif, une API ou un service web devient vulnérable à cinq classes d'abus distinctes : déni de service volumique (DoS), brute force d'authentification (credential stuffing), scraping et énumération massive de données (BOLA enumeration, scraping de contenu), abus de business logic (achats massifs, ticket scalping), et déni de service algorithmique (zip bomb, regex catastrophic backtracking, GraphQL queries imbriquées). Implémenter un rate limiting robuste implique cinq couches cumulatives (CDN edge, reverse proxy, API gateway, application Redis, business logic), le choix d'un algorithme adapté (Token bucket dominant en 2026, Sliding window counter pour précision), et l'usage des headers HTTP standardisés par RFC 9651 (mai 2024). Cet article détaille les 5 classes d'abus défendues, les 5 algorithmes principaux comparés, les patterns d'implémentation par couche avec code Redis, NGINX et Cloudflare, les headers HTTP standards, les techniques de bypass et leurs défenses, le rate limiting distribué multi-instance, le tuning et le monitoring opérationnel.
Pourquoi le rate limiting : 5 classes d'abus défendues
Sans rate limiting, cinq familles d'attaques ou abus deviennent triviales.
1. Déni de service volumique (DoS)
Un attaquant envoie un volume massif de requêtes pour saturer le serveur (CPU, mémoire, connexions, base de données). Sans rate limit, un script Python basique peut générer 10 000+ requêtes/seconde depuis une seule machine, suffisant pour mettre à genou la plupart des APIs non protégées.
Le DDoS volumique avec attaquant distribué (botnet) ne se résout pas par rate limiting per-IP seul, mais le rate limiting reste la première couche de défense applicative.
2. Brute force d'authentification
Tester systématiquement des combinaisons login/password ou des codes OTP/SMS jusqu'à trouver la bonne. Sans rate limit sur l'endpoint d'authentification, un attaquant peut tester :
- 10 000 mots de passe par seconde sur un endpoint
/api/auth/login. - 1 million de codes OTP 6 chiffres en quelques minutes (1M combinaisons possibles).
- Credential stuffing avec liste de credentials volés (par exemple Have I Been Pwned 12 milliards d'entrées 2026).
Documenté dans OWASP API Security Top 10 API4:2023 et OWASP API2:2023 (Broken Authentication).
3. Scraping et énumération massive
Extraction de données massives via API publique :
- Énumération BOLA : tester séquentiellement
/api/orders/1, 2, 3, ...pour exfiltrer toutes les commandes (variant de l'incident T-Mobile janvier 2023, 37M comptes). - Scraping de catalogues : extraction de tous les produits, prix, avis pour un concurrent.
- Énumération de comptes : tester
/api/users/check?email=...pour identifier les comptes existants.
Sans rate limit sémantique, l'attaquant exfiltre une base entière en quelques heures.
4. Abus de business logic
Patterns spécifiques à la logique métier :
- Ticket scalping : achat massif automatisé de tickets pour revente.
- Promo code abuse : test de tous les codes promo possibles ou utilisation massive d'un code unique.
- Account creation spam : création de milliers de faux comptes pour spam ou manipulation.
- Multi-redemption : utilisation répétée d'un coupon à usage unique avant invalidation backend.
OWASP API6:2023 (Unrestricted Access to Sensitive Business Flows) est la classe formalisée pour cette catégorie.
5. Déni de service algorithmique
Requêtes peu nombreuses mais coûteuses qui saturent le serveur :
- Zip bomb : archive 42KB qui explose en 4,5 PB à la décompression.
- Regex catastrophic backtracking (ReDoS) : input crafted qui fait timeout une regex côté serveur.
- GraphQL queries imbriquées profondes : query qui demande tout le graphe en cascade.
- GraphQL aliases batch : 1000 mutations dans une seule requête HTTP.
- Compression bombs : payload compressé qui explose en mémoire.
Le rate limiting volumique standard ne couvre pas ces cas. Compléter avec limites sémantiques (max depth GraphQL, max body size, max regex execution time).
Les 5 algorithmes de rate limiting
Comparaison des algorithmes principaux. Choix selon précision requise, tolérance bursts, coût d'implémentation.
1. Fixed Window Counter
Le plus simple. Compteur incrémenté pour chaque requête, reset toutes les N secondes.
Window 0-60s: [count=0 → 100, OK | count=101+, 429]
Window 60-120s: [count=0 → 100, OK | count=101+, 429]Avantages : simple, peu coûteux. Inconvénient : effet de bord aux frontières (un client peut faire 100 req à 0:59 puis 100 req à 1:00 = 200 req en 1 seconde réelle).
Convient pour : APIs simples, prototypes, contextes où la précision n'est pas critique.
2. Sliding Window Log
Stockage du timestamp de chaque requête. Pour valider : compter les timestamps dans la fenêtre [maintenant - N, maintenant].
Avantages : précision parfaite, pas d'effet de bord. Inconvénient : coût mémoire élevé (stocker chaque timestamp).
Convient pour : APIs faible volume avec exigence de précision absolue.
3. Sliding Window Counter
Compromis entre Fixed Window et Sliding Window Log. Combine les compteurs de la fenêtre courante et précédente avec pondération linéaire.
Fenêtre précédente (0-60s) : 80 requêtes
Fenêtre courante (60-120s) : 30 requêtes, on est à 90s (50 % dans la fenêtre)
Estimation pondérée : 80 × (1 - 0.5) + 30 = 70 requêtes effectives
Si limite = 100, OKAvantages : précision proche du sliding log, coût mémoire constant. Inconvénient : approximation (acceptable en pratique).
Convient pour : majorité des APIs production. Algorithme dominant en 2026 pour les solutions modernes.
4. Token Bucket
Le bucket se remplit à débit constant (par exemple 10 tokens/seconde). Chaque requête consomme un token. Si bucket vide, requête refusée.
Bucket capacity: 100 tokens (burst max)
Refill rate: 10 tokens/second
Burst possible : 100 requêtes en 1 seconde puis attendre.
Régime stable : 10 requêtes/seconde sustained.Avantages : permet bursts courts tolérés, comportement intuitif pour développeurs, implémentation simple Redis. Inconvénient : moins prévisible que sliding window pour limites strictes.
Convient pour : APIs publiques (utilisateurs apprécient la tolérance burst), pattern dominant 2026 pour la majorité des cas.
5. Leaky Bucket
Variante du token bucket. Les requêtes entrantes remplissent le bucket, les requêtes sortent à débit constant. Si bucket plein, requêtes refusées.
Avantages : lisse les bursts, garantit débit constant côté serveur. Inconvénient : peut imposer latence aux requêtes valides en cas de burst.
Convient pour : protection downstream (par exemple : API qui consomme une API tierce avec rate limit strict, lisse les requêtes vers le tiers).
Comparaison synthétique
| Algorithme | Précision | Coût mémoire | Tolérance burst | Cas d'usage type |
|---|---|---|---|---|
| Fixed Window | Moyenne (effet de bord) | Très faible | Possible aux frontières | Prototypes, APIs simples |
| Sliding Window Log | Parfaite | Très élevé | Aucune | APIs très sensibles, faible volume |
| Sliding Window Counter | Très bonne | Faible | Limitée | Production moderne, APIs critiques |
| Token Bucket | Bonne | Faible | Configurable | API publique standard, dominant 2026 |
| Leaky Bucket | Bonne | Faible | Lisse | Protection downstream API tierces |
Couche 1 — Edge / CDN (Cloudflare, AWS WAF, Akamai)
Premier filet de défense. Rate limiting au plus proche du client, avant même d'atteindre l'infrastructure.
Cloudflare Rate Limiting
# Configuration via Cloudflare Dashboard ou API
Rule: Login Brute Force Protection
- If: URI Path equals "/api/auth/login"
- Method: POST
- Threshold: 10 requests per 1 minute per IP
- Action: Block for 1 hour
- Response code: 429Cloudflare offre rate limiting basique gratuit, plus avancé en plans Business ($200/mois) et Enterprise.
AWS WAF Rate-based rules
{
"Name": "RateLimitPerIP",
"Priority": 1,
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
},
"Action": { "Block": {} },
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "RateLimitPerIP"
}
}Limit minimum 100 requêtes par IP sur fenêtre 5 minutes.
Avantages couche edge
- Absorbe les attaques volumiques sans charger l'origine.
- Protection avant que la requête n'atteigne le réseau interne.
- Géo-distribuée naturellement.
Limites
- Granularité limitée (souvent uniquement par IP).
- Pas de connaissance du contexte applicatif (ne peut pas rate limit par user ID).
- Cas d'usage simples uniquement.
Couche 2 — Reverse proxy (Nginx, HAProxy)
Couche application-aware sans modifier le backend.
Nginx avec limit_req_zone
http {
# Définition de la zone : 10 MB pour stocker les compteurs IP
limit_req_zone $binary_remote_addr zone=api_general:10m rate=100r/s;
limit_req_zone $binary_remote_addr zone=auth_strict:10m rate=5r/m;
# Limit par utilisateur authentifié (si JWT décodé via auth_request)
limit_req_zone $http_x_user_id zone=user_quota:10m rate=1000r/m;
# Limite de connexions simultanées
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
server {
listen 443 ssl;
# Toutes les routes : 100 req/sec par IP avec burst 200
location / {
limit_req zone=api_general burst=200 nodelay;
limit_conn conn_per_ip 50;
proxy_pass http://backend;
}
# Login : très restrictif
location /api/auth/login {
limit_req zone=auth_strict burst=2;
proxy_pass http://backend;
}
# Endpoints authentifiés : limite par utilisateur
location /api/v1/ {
limit_req zone=user_quota burst=100;
proxy_pass http://backend;
}
}
}Headers retour Nginx
# Custom error page pour 429 avec header Retry-After
error_page 429 /429.json;
location = /429.json {
default_type application/json;
add_header Retry-After 60 always;
return 429 '{"error": "rate_limited", "retry_after": 60}';
}HAProxy équivalent
frontend api_front
bind *:443 ssl crt /etc/ssl/cert.pem
# Tracking par IP
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
# Refus si > 100 req/10sec par IP
http-request deny if { sc_http_req_rate(0) gt 100 }
default_backend api_backCouche 3 — API Gateway (Kong, Apigee, AWS API Gateway)
Couche dédiée API avec rate limiting riche en fonctionnalités.
Kong Rate Limiting plugin
# Plugin Kong déclaratif
plugins:
- name: rate-limiting
config:
second: 5
minute: 100
hour: 1000
day: 10000
policy: redis
redis_host: redis.internal
redis_port: 6379
fault_tolerant: true
hide_client_headers: false
limit_by: consumer # ou ip, credential, headerHeaders automatiquement ajoutés :
HTTP/1.1 200 OK
RateLimit-Limit: 100
RateLimit-Remaining: 42
RateLimit-Reset: 35
X-RateLimit-Limit-Minute: 100
X-RateLimit-Remaining-Minute: 42AWS API Gateway Usage Plans
Quota globaux + per-key, configurés par Usage Plan associé à API key.
# CloudFormation snippet
UsagePlan:
Type: AWS::ApiGateway::UsagePlan
Properties:
UsagePlanName: standard
Throttle:
RateLimit: 100 # requêtes/sec moyennes
BurstLimit: 200 # burst max
Quota:
Limit: 1000000 # requêtes par période
Period: MONTHComparaison gateways 2026
| Gateway | Plugin rate limit | Backend stockage | Particularité |
|---|---|---|---|
| Kong | rate-limiting (officiel) | Redis, local, cluster | Riche, déclaratif YAML |
| Apigee | Quota policy | Apigee distributed | Enterprise mature |
| AWS API Gateway | Usage Plans | AWS-managed | Native AWS, simple |
| Azure API Management | Rate limit policies | Azure-managed | Native Azure, XML policies |
| Tyk | Rate limit middleware | Redis | OSS + Enterprise, GraphQL natif |
| KrakenD | Rate limit middleware | Local in-memory | Très performant |
| Traefik | Plugin rate-limit | Redis | K8s-native |
Couche 4 — Application avec Redis
Pour rate limiting ultra-précis et personnalisable au-delà des gateways.
Token Bucket atomic via Redis Lua script
Le pattern recommandé en 2026 : script Lua atomique exécuté côté Redis pour éviter les race conditions.
-- token_bucket.lua
-- KEYS[1] = clé du bucket (par exemple : "rate:user:123")
-- ARGV[1] = capacité max (max tokens)
-- ARGV[2] = refill rate (tokens par seconde)
-- ARGV[3] = timestamp courant (UNIX seconds)
-- ARGV[4] = tokens à consommer (généralement 1)
local capacity = tonumber(ARGV[1])
local rate = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local consume = tonumber(ARGV[4])
-- Récupération état précédent
local bucket = redis.call("HMGET", KEYS[1], "tokens", "last_refill")
local tokens = tonumber(bucket[1]) or capacity
local last_refill = tonumber(bucket[2]) or now
-- Calcul des tokens accumulés depuis dernier refill
local elapsed = now - last_refill
local refilled = math.min(capacity, tokens + elapsed * rate)
-- Tentative de consommation
if refilled >= consume then
refilled = refilled - consume
redis.call("HMSET", KEYS[1], "tokens", refilled, "last_refill", now)
redis.call("EXPIRE", KEYS[1], 3600) -- TTL pour cleanup
return {1, refilled} -- 1 = autorisé, refilled = tokens restants
else
redis.call("HMSET", KEYS[1], "tokens", refilled, "last_refill", now)
redis.call("EXPIRE", KEYS[1], 3600)
return {0, refilled} -- 0 = refusé
endUsage côté Python :
import redis
import time
r = redis.Redis(host="redis.internal", decode_responses=True)
# Charger le script une fois (Redis cache le SHA)
TOKEN_BUCKET_SCRIPT = open("token_bucket.lua").read()
script_sha = r.script_load(TOKEN_BUCKET_SCRIPT)
def check_rate_limit(user_id: str, capacity: int = 100, rate: float = 10.0) -> tuple[bool, int]:
key = f"rate:user:{user_id}"
now = int(time.time())
result = r.evalsha(script_sha, 1, key, capacity, rate, now, 1)
allowed = bool(result[0])
remaining = int(result[1])
return allowed, remaining
# Usage dans handler API
def api_handler(user_id: str):
allowed, remaining = check_rate_limit(user_id)
if not allowed:
raise HTTPException(
status_code=429,
detail="Rate limited",
headers={
"Retry-After": "10",
"RateLimit-Remaining": str(remaining),
}
)
# ... traiter la requêteSliding Window Counter via Redis Sorted Set
import redis
import time
r = redis.Redis(host="redis.internal")
def check_sliding_window(key: str, limit: int, window_seconds: int) -> bool:
now = time.time() * 1000 # millisecondes
cutoff = now - window_seconds * 1000
pipe = r.pipeline()
# Supprimer entrées hors fenêtre
pipe.zremrangebyscore(key, 0, cutoff)
# Compter requêtes restantes dans fenêtre
pipe.zcard(key)
# Ajouter requête courante
pipe.zadd(key, {str(now): now})
# TTL pour cleanup
pipe.expire(key, window_seconds)
results = pipe.execute()
count = results[1]
return count < limit
# Usage : 100 requêtes par minute
allowed = check_sliding_window("rate:user:123", limit=100, window_seconds=60)Couche 5 — Business logic (compteurs sémantiques)
Au-delà du rate limiting volumique, les compteurs business spécifiques.
# Exemples de compteurs business en addition du rate limiting volumique
# Maximum 10 transactions de paiement par jour par compte
def can_make_payment(user_id: str) -> bool:
today = datetime.now().strftime("%Y-%m-%d")
key = f"payments:{user_id}:{today}"
count = r.incr(key)
if count == 1:
r.expire(key, 86400) # TTL 24h
return count <= 10
# Maximum 3 SMS OTP par heure par numéro
def can_send_otp(phone: str) -> bool:
hour = datetime.now().strftime("%Y-%m-%d-%H")
key = f"otp:{phone}:{hour}"
count = r.incr(key)
if count == 1:
r.expire(key, 3600)
return count <= 3
# Maximum 5 reset password par jour par compte
def can_reset_password(email: str) -> bool:
today = datetime.now().strftime("%Y-%m-%d")
key = f"reset:{email}:{today}"
count = r.incr(key)
if count == 1:
r.expire(key, 86400)
return count <= 5Ces compteurs business sont indépendants du rate limiting volumique et défendent contre les abus de business logic (OWASP API6:2023).
Headers HTTP standards (RFC 9651)
Standardisé en mai 2024 par RFC 9651 RateLimit Header Fields for HTTP. Cinq headers définis.
Headers de réponse
| Header | Signification | Exemple |
|---|---|---|
| RateLimit-Limit | Limite totale dans la fenêtre | RateLimit-Limit: 100 |
| RateLimit-Remaining | Requêtes restantes | RateLimit-Remaining: 42 |
| RateLimit-Reset | Secondes avant reset | RateLimit-Reset: 35 |
| RateLimit-Policy | Description de la politique | RateLimit-Policy: 100;w=60 (100 req par 60s) |
| Retry-After | Délai avant retry possible (sur 429) | Retry-After: 60 ou date HTTP |
Pattern complet
# Réponse normale avec headers indicatifs
HTTP/1.1 200 OK
Content-Type: application/json
RateLimit-Limit: 100
RateLimit-Remaining: 42
RateLimit-Reset: 35
RateLimit-Policy: 100;w=60
# Réponse 429 avec Retry-After
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 35
Retry-After: 35
{
"error": "rate_limited",
"message": "Trop de requêtes. Réessayez dans 35 secondes.",
"retry_after": 35
}Headers legacy X-RateLimit-*
Beaucoup d'APIs utilisent encore les headers legacy non standardisés (popularisés par GitHub, Twitter avant la RFC 9651) :
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset(parfois timestamp UNIX, parfois secondes restantes selon API)
Compatibilité descendante recommandée : émettre les deux variantes pour transition douce.
Patterns de bypass et défenses
Cinq techniques de bypass courantes et leurs contre-mesures.
Bypass 1 — IP rotation via proxies résidentiels
Attaquant utilise des proxies résidentiels (Bright Data, Oxylabs) pour distribuer ses requêtes sur des milliers d'IPs résidentielles.
Défense : compléter rate limit per IP avec rate limit per token utilisateur (l'attaquant doit créer un compte ou voler un token, plus coûteux). Détection comportementale (CAPTCHA, fingerprinting).
Bypass 2 — Header IP spoofing
Attaquant modifie X-Forwarded-For, X-Real-IP, X-Client-IP pour faire croire à des IPs différentes.
Défense : configurer le reverse proxy pour utiliser uniquement l'IP réelle de la connexion TCP, pas les headers HTTP arbitraires (sauf si une infrastructure CDN/LB en frontage de confiance les fournit).
# Nginx : utiliser real IP via header X-Forwarded-For
# UNIQUEMENT si trusted proxy en frontage
set_real_ip_from 10.0.0.0/8; # Cloudflare, internal LB
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# Sinon, utiliser $remote_addr (IP TCP) directementBypass 3 — Race conditions
Plusieurs requêtes simultanées qui passent toutes le check de rate limit avant que le compteur soit incrémenté.
Défense : opérations atomiques côté Redis (script Lua, INCR + EXPIRE atomique).
Bypass 4 — Variations d'URL
Attaquant exploite les variations d'URL non normalisées : /api/login, /api//login, /api/login/, /api/LOGIN traités séparément par le rate limiter.
Défense : normalisation de l'URL avant de calculer la clé de rate limit (lowercase, trailing slash uniforme, double slashes éliminés).
Bypass 5 — Endpoints avec pagination
Attaquant fait /api/users?page=1&size=10000 pour exfiltrer 10 000 records en une seule requête, contournant le rate limit per-request.
Défense : limite max sur paramètres de pagination (par exemple size max = 100), rate limiting basé sur les bytes ou records retournés (plus complexe mais possible).
Rate limiting distribué multi-instance
Pour APIs déployées sur plusieurs instances, le rate limiting local par instance est insuffisant (les compteurs ne sont pas partagés).
Pattern Redis centralisé
Tous les instances API consultent le même Redis pour vérifier les compteurs. Performance acceptable jusqu'à plusieurs milliers de req/s grâce à Lua scripts atomiques.
Pattern Envoy ratelimit service
Pour très grande échelle (millions req/s), Envoy ratelimit service (gRPC) avec backend Redis ou autre. Architecture standard chez Lyft (origine Envoy), Stripe, GitHub.
Approximate counters distribués
Pour échelle extrême avec tolérance à l'imprécision : algorithmes type HyperLogLog ou Counting Bloom Filters distribués. Sacrifient précision au profit de la performance.
Monitoring et tuning
Trois métriques essentielles à instrumenter.
Métriques opérationnelles
# Métriques Prometheus typiques
rate_limit_blocked_total{key_type="ip", endpoint="/api/auth/login"}
rate_limit_allowed_total{key_type="user", endpoint="/api/orders"}
rate_limit_threshold_remaining{key="user:123", endpoint="/api/orders"}
# Alerting :
# - Volume rate_limit_blocked anormalement élevé sur un endpoint = attaque ou seuil mal tuné
# - Aucun rate_limit_blocked depuis X jours = peut-être seuils trop laxistesTuning des seuils
Démarrer en mode "observe" (logging uniquement, pas de blocage) pendant 2 à 4 semaines. Analyser :
- Distribution des requêtes par utilisateur (P50, P95, P99 par minute).
- Identifier les utilisateurs heavy hitters légitimes.
- Fixer le seuil de blocage à environ P99 + 50 % pour ne pas bloquer les utilisateurs légitimes intensifs.
Whitelist documentée
Maintenir une liste des partenaires premium et systèmes internes avec quotas augmentés. Centraliser dans la configuration (par exemple : YAML déclaratif) pour traçabilité.
# Exemple config rate limit avec exceptions
rate_limits:
default:
per_ip: 100 # req/sec
per_user: 1000 # req/min
exceptions:
partners:
- id: partner_premium_a
per_user: 10000
contact: contact-a@example.test
contract_ref: SLA-2026-001
- id: monitoring_internal
per_user: 100000
contact: ops@example.test
purpose: "Datadog, New Relic synthetic checks"Points clés à retenir
- Le rate limiting défend contre 5 classes d'abus distinctes : DoS volumique, brute force d'authentification, scraping et énumération massive (BOLA), abus de business logic, déni de service algorithmique. OWASP API4:2023 le classe parmi les top vulnérabilités API.
- Cinq algorithmes principaux : Fixed Window (simple), Sliding Window Log (parfait mais coûteux), Sliding Window Counter (compromis dominant), Token Bucket (tolère bursts, pattern dominant 2026 pour APIs publiques), Leaky Bucket (lisse pour protection downstream).
- Cinq couches d'implémentation cumulatives : edge/CDN (Cloudflare, AWS WAF), reverse proxy (Nginx, HAProxy), API gateway (Kong, AWS API Gateway), application (Redis avec Lua scripts atomiques), business logic (compteurs sémantiques par action métier).
- Headers HTTP standardisés par RFC 9651 (mai 2024) : RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, RateLimit-Policy plus Retry-After (RFC 6585) sur HTTP 429. Compatibilité X-RateLimit-* legacy à conserver pour transition.
- Le rate limiting per-IP seul est trivialement contourné par rotation IP. Toujours combiner per-IP + per-token utilisateur + per-business-action en couches cumulatives. Démarrer en mode observe avant blocage strict pour calibrer les seuils.
Pour aller plus loin
- Qu'est-ce que la sécurité des API - rate limiting comme couche de défense API parmi 4 couches.
- Méthodologie de pentest API - tests de bypass de rate limiting en pentest offensif.
- Sécurité des uploads de fichiers - rate limiting spécifique aux endpoints d'upload.
- Authentification d'API : les bases - rate limiting auth spécifique pour brute force prevention.





