Overview
Rate limiting is a critical security feature that protects your application from abuse, brute force attacks, and resource exhaustion. django-allauth includes comprehensive rate limiting that’s enabled by default and requires no external dependencies beyond Django’s cache framework.How Rate Limiting Works
Rate limits restrict the number of times an action can be performed within a time window, tracked per:- IP address - Prevent attacks from specific sources
- User - Limit actions per authenticated user
- Key - Custom identifier (email, username, phone)
Rate Limit Syntax
Rate limits use a concise string format:s- secondsm- minutesh- hoursd- days
ip- Client IP addressuser- Authenticated userkey- Action-specific key (email, username, etc.)
Default Rate Limits
django-allauth ships with sensible defaults configured for security: From source (app_settings.py:260-304):
Customizing Rate Limits
Override Specific Limits
Modify individual rate limits while keeping defaults:Disable Specific Limits
Set toNone to disable a specific rate limit:
Disable All Rate Limits
Useful for development or when using external rate limiting (e.g., Cloudflare, AWS WAF).
Rate Limit Actions
Authentication Actions
login
login
Default: Applied on every login form submission.
30/m/ipGeneral login attempts (successful or failed).login_failed
login_failed
Default: When exceeded, users are temporarily locked out even with correct credentials.From source (
10/m/ip,5/5m/keyCritical for security - Prevents brute force password attacks.rate_limits.rst:43-47):Restricts the allowed number of failed login attempts. When exceeded, the user is prohibited from logging in for the remainder of the rate limit. Important: while this protects the allauth login view, it does not protect Django’s admin login from being brute forced.
signup
signup
Default: Prevents automated account creation and spam registrations.
20/m/ipUser registration attempts.login_by_code
login_by_code
Default: The
20/m/ip,3/m/keyRequesting passwordless login codes.key is the email address requesting the code.Password Actions
reset_password
reset_password
Default: The
20/m/ip,5/m/keyRequesting password reset emails.key is the email address for which the reset is requested.Prevents:- Email bombing (spamming user with reset emails)
- Account enumeration attempts
reset_password_from_key
reset_password_from_key
Default: Prevents brute-forcing the new password field.
20/m/ipSubmitting the password reset form (after clicking the link).change_password
change_password
Default: Prevents password change abuse if an account is compromised.
5/m/userChanging password for authenticated users.Email Actions
confirm_email
confirm_email
Default: The
1/3m/key (link) or 1/10s/key (code)Sending email verification messages.key is the email address being verified.Automatic configuration from source (app_settings.py:270-276):manage_email
manage_email
Default: Prevents rapid-fire email additions/removals.
10/m/userEmail management actions (add, remove, set primary).Other Actions
reauthenticate
reauthenticate
Default:
10/m/userRe-entering credentials for sensitive operations.change_phone
change_phone
Default:
1/m/userChanging phone number.verify_phone
verify_phone
Default: The
1/30s/key,3/m/ipSending phone verification codes.key is the phone number.IP Address Detection
Critical Security Consideration: Accurate IP detection is essential for rate limiting to work correctly.django-allauth cannot reliably determine the client IP address out of the box because the correct method depends on your infrastructure (load balancers, proxies, CDNs).The
X-Forwarded-For header can be trivially spoofed, allowing attackers to bypass rate limits entirely.Trusted Proxy Configuration
Configure how many proxies are under your control:ALLAUTH_TRUSTED_PROXY_COUNT = 1:
X-Forwarded-For: client, proxy1, proxy2- Takes the IP from position:
countfrom the right - Result:
proxy1(second from right)
rate_limits.rst:36-45):
As theX-Forwarded-Forheader can be spoofed, you need to configure the number of proxies that are under your control and hence, can be trusted. The default is 0, meaning, no proxies are trusted. As a result, theX-Forwarded-Forheader will be disregarded by default.
Trusted Header Configuration
If your proxy sets a custom header (e.g., Cloudflare, nginx):Only use
ALLAUTH_TRUSTED_CLIENT_IP_HEADER if you’re certain the header is set by a trusted component and cannot be spoofed by clients.Custom IP Detection
Override the adapter for complex scenarios:Testing IP Detection
Rate Limit Implementation
Internal Architecture
From source (core/internal/ratelimit.py:1-11):
Rate limiting uses cache-based tracking with non-atomic operations. This means:
- ✅ Performant and scalable
- ✅ No database overhead
- ⚠️ Slight overruns possible under high concurrency (acceptable trade-off)
Cache Key Format
From source (core/internal/ratelimit.py:93-117):
Consumption Algorithm
From source (core/internal/ratelimit.py:120-147):
Programmatic Rate Limiting
Check Rate Limit Without Consuming
Consume Rate Limit
Consume with Exception
Clear Rate Limit
Custom Rate Limit Actions
Define your own rate-limited actions:429 Response Customization
Custom Template
Create429.html in your templates directory:
Custom Handler
Define a custom 429 handler in your root URLconf:Headless API Response
For headless/API mode:Testing with Rate Limits
Disable for Tests
Test Rate Limit Behavior
Monitoring Rate Limits
Log Rate Limit Events
Metrics Collection
Cache Backend Recommendations
Redis (Recommended)
- ✅ High performance
- ✅ Atomic operations
- ✅ TTL support
- ✅ Distributed (multiple app servers)
Memcached
- ✅ Fast
- ✅ Simple setup
- ✅ Distributed
Database Cache
- ⚠️ No Redis/Memcached available
- ⚠️ Lower traffic requirements
- ✅ Need cache persistence
Best Practices
Start Conservative
Start Conservative
Begin with stricter limits and relax based on monitoring:Gradually increase if legitimate users are affected.
Layer Multiple Limits
Layer Multiple Limits
Use both IP and key-based limits for defense in depth:
Monitor and Alert
Monitor and Alert
Track rate limit hits to detect attacks:
Secure IP Detection
Secure IP Detection
Always configure IP detection for your infrastructure:
Use Appropriate Cache
Use Appropriate Cache
Redis or Memcached in production:
Troubleshooting
Rate Limits Not Working
Rate Limits Not Working
Check cache backend:If using
DummyCache, rate limits won’t work.All Requests Rate Limited
All Requests Rate Limited
Check IP detection:If all requests show the same IP (e.g., load balancer), configure trusted proxies.
Legitimate Users Blocked
Legitimate Users Blocked
Increase limits or use more specific keys:
Rate Limits Reset Too Quickly
Rate Limits Reset Too Quickly
Check cache TTL and duration:
Next Steps
Authentication Flows
See where rate limits are applied in login/signup flows
Email Verification
Learn about email verification rate limiting
