Avancé
🧠 Fondamentaux
30 XP
0 personnes ont réussi
Rate limiter comme middleware Django
Le rate limiting (limitation de debit), c'est le videur de ton API : il limite le nombre de requêtes qu'un client peut faire dans un intervalle de temps. Ca protege contre les abus et les attaques par deni de service.
Dans une vraie application Django, on utiliserait django-ratelimit ou DRF throttling. Mais le principe reste le meme : pour chaque adresse IP, on garde en mémoire les timestamps des dernières requêtes.
L'adresse IP du client est accessible dans Django via request.META.get('REMOTE_ADDR').
Écris un middleware RateLimitMiddleware (new style) qui : - Dans __init__, recoit get_response, max_requests (défaut 10) et window_seconds (défaut 60) - Stocke self.requests = {} (IP vers liste de timestamps) - Dans __call__ : 1. Recupere l'IP avec request.META.get('REMOTE_ADDR', 'unknown') 2. Nettoie les timestamps plus vieux que la fenetre 3. Si le quota est depasse, retourne directement un JsonResponse avec {'error': 'Rate limit exceeded'} et status 429 (sans appeler get_response) 4. Sinon, enregistre le timestamp et continue normalement
Exemple :
import time mw = RateLimitMiddleware(lambda r: HttpResponse('ok'), max_requests=2, window_seconds=60) req = HttpRequest() req.META['REMOTE_ADDR'] = '1.2.3.4' mw(req) # OK mw(req) # OK resp = mw(req) # 429 Rate limit exceeded
import django
from django.conf import settings
if not settings.configured:
settings.configure(
DATABASES={},
INSTALLED_APPS=['django.contrib.contenttypes'],
DEFAULT_AUTO_FIELD='django.db.models.BigAutoField',
)
django.setup()
import time
from django.http import HttpRequest, HttpResponse, JsonResponse
class RateLimitMiddleware:
def __init__(self, get_response, max_requests=10, window_seconds=60):
self.get_response = get_response
self.max_requests = max_requests
self.window_seconds = window_seconds
self.requests = {}
def __call__(self, request):
ip = request.META.get('REMOTE_ADDR', 'unknown')
now = time.time()
if ip not in self.requests:
self.requests[ip] = []
window_start = now - self.window_seconds
self.requests[ip] = [t for t in self.requests[ip] if t > window_start]
if len(self.requests[ip]) >= self.max_requests:
return JsonResponse({'error': 'Rate limit exceeded'}, status=429)
self.requests[ip].append(now)
return self.get_response(request)