# DRF Throttling: Verwendung von „scope“ – Vergleich von `ScopedRateThrottle` und `UserRateThrottle`-Vererbung In DRF gibt es zwei häufig verwendete Muster, wenn man scope-basiertes Throttling einsetzt. * **Muster A**: Eine eigene Klasse erstellen, die von `UserRateThrottle` (oder `SimpleRateThrottle`) erbt und dort einen **festen scope** definiert. Diese Klasse wird dann direkt über `throttle_classes` an der View verwendet. * **Muster B**: `ScopedRateThrottle` in `DEFAULT_THROTTLE_CLASSES` registrieren und in der View lediglich `throttle_scope = "login"` setzen. Die Frage „Gibt es letztlich keinen Unterschied?“ lässt sich so beantworten: > **Wenn du nur ein einzelnes Rate-Limit auf Basis von „user ID (oder nicht authentifizierter IP) + scope“ brauchst, ist das Ergebnis nahezu identisch.** Unterschiede zeigen sich jedoch bei **Fehlkonfigurationen (Absicherung), Erweiterbarkeit (mehrere Richtlinien/benutzerdefinierte Kriterien) und der Code-Struktur (settings-zentriert vs. code-zentriert)**. --- ## Gemeinsamkeit: Beide erzeugen einen Schlüssel aus „scope + (user ID oder IP)“ {#sec-431a00e0f2d6} * `ScopedRateThrottle` baut den Schlüssel aus `throttle_scope` (falls vorhanden) plus user ID bzw. IP und sucht die passende Rate in `DEFAULT_THROTTLE_RATES`. * `UserRateThrottle` drosselt ebenfalls nach user ID (authentifiziert) bzw. IP (nicht authentifiziert). Für mehrere Richtlinien empfiehlt DRF, die Klasse zu erben und unterschiedliche `scope`-Werte zu setzen. --- ## Unterschied 1) Wo wird der scope definiert? – View-Attribut vs. Klassen-Attribut {#sec-d624b1b24a23} ### Muster A: scope fest in der Klasse (explizit) {#sec-8806ad9d3f5f} ```python from rest_framework.throttling import UserRateThrottle from rest_framework.views import APIView class CustomDomainSaveThrottle(UserRateThrottle): scope = "custom_domain_save" class SaveCustomDomainView(APIView): throttle_classes = [CustomDomainSaveThrottle] ``` * Der `scope` ist **in der Klasse** festgelegt. * Die View muss lediglich die Klasse referenzieren. * Tippfehler im `scope`-String werden reduziert – der Klassenname dient praktisch als Dokumentation. ### Muster B: scope in der View, gemeinsamer Throttle (settings-zentriert) {#sec-21174dce63ed} ```python REST_FRAMEWORK = { "DEFAULT_THROTTLE_CLASSES": [ "rest_framework.throttling.ScopedRateThrottle", ], "DEFAULT_THROTTLE_RATES": { "login": "5/min", } } from rest_framework.views import APIView class LoginView(APIView): throttle_scope = "login" ``` * Der `scope` wird **direkt in der View** gesetzt. * Der gemeinsame Throttle (`ScopedRateThrottle`) liest `throttle_scope` aus und holt die Rate aus den Einstellungen. * Der Code bleibt kompakt, und Richtlinien lassen sich zentral in den settings verwalten. --- ## Unterschied 2) Wer stellt die Anwendung sicher? – Globale Registrierung vs. View-spezifisches Anhängen {#sec-693e9b27f525} ### Punkt zu Muster B (häufig missverstanden) {#sec-579edda7168e} Selbst wenn `ScopedRateThrottle` in `DEFAULT_THROTTLE_CLASSES` registriert ist, **greift es nicht bei Views ohne `throttle_scope`**. Eine globale Registrierung throttelt also nicht automatisch alle Endpoints. ### Vorteil von Muster A {#sec-1d7d8c13bc83} Ohne globale Einstellungen zu verändern, kann man gezielt **bestimmte Views** mit dem gewünschten Throttle „ausstatten“. Das ist nützlich, wenn settings nur eingeschränkt angepasst werden dürfen oder nur einzelne Endpoints streng limitiert werden sollen. --- ## Unterschied 3) Erweiterbarkeit: Mehr als ein einzelnes Limit – Muster A ist im Vorteil {#sec-76818ce0201b} Die beiden Muster wirken ähnlich, solange jede View genau **einen scope und ein Limit** hat. Sobald mehr nötig ist, werden die Unterschiede deutlich. ### 1) Mehrere Throttles (z. B. Burst + Sustained) {#sec-c0ea02305999} Die DRF-Dokumentation zeigt ein Muster mit mehreren `UserRateThrottle`-Subklassen für Burst- und Sustained-Limits. ```python class Burst(UserRateThrottle): scope = "burst" class Sustained(UserRateThrottle): scope = "sustained" class SearchView(APIView): throttle_classes = [Burst, Sustained] ``` Mit reinem `ScopedRateThrottle` lässt sich **nicht** elegant „zwei scopes auf einer View“ ausdrücken – dafür braucht man wieder eigene Klassen (oder zusätzliche Logik). ### 2) Andere Kriterien als user ID/IP {#sec-39de8e67072d} `ScopedRateThrottle` arbeitet standardmäßig mit user ID bzw. IP. In der Praxis kommen jedoch schnell Anforderungen wie diese hinzu: * Login: Limitierung nach **IP + Benutzername** (z. B. gegen account-targeted Angriffe). * Multi-Tenant-Systeme: Limitierung nach **tenant_id**. * API-Keys: Limitierung **pro Schlüssel**. Diese Fälle erfordern typischerweise eine Anpassung von `get_cache_key()` und führen damit zu einer **benutzerdefinierten Throttle-Klasse** – also zu Muster A. --- ![Zwei Schlüssel, die eine API-Verbindung öffnen](/media/editor_temp/6/e98f026a-a38e-43ca-8c86-fa7966dd3cdf.png) ## Was sollte man wählen? {#sec-1cf080d47909} ### Für die meisten „View-spezifischen Rate-Limits“ → Muster B (`ScopedRateThrottle`) {#sec-924ae91c07d2} * Minimaler Code * Zentrale Verwaltung über settings * Nur Views mit `throttle_scope` werden limitiert ### Wenn eines der folgenden zutrifft → Muster A (Vererbung/benutzerdefinierte Klasse) {#sec-335f8d95a231} * Mehrere Limits (z. B. Burst + Sustained) gleichzeitig auf einer View * Kriterien jenseits von user ID/IP (z. B. IP + Benutzername, Tenant, API-Key) * Globale Einstellungen sollen nicht verändert werden, aber bestimmte Views müssen throttled werden * Klassenname soll als „Dokumentation“ dienen **Weiterführender Artikel:** * [DRF Throttling vollständig beherrschen: Einstellungen, Anwendung und Custom-Guide](/ko/whitedec/2026/1/26/drf-throttling-complete-guide/)