Skip to main content

Overview

Email verification is a critical security feature that confirms users own the email addresses they register with. django-allauth provides flexible email verification with multiple strategies to balance security and user experience.
Email verification prevents users from registering with email addresses they don’t control, which could be used for spam, impersonation, or account takeover.

Verification Methods

django-allauth offers three main verification approaches:
Most Secure - Users cannot log in until email is verified.
Flow:
Best for applications handling sensitive data
Prevents fake accounts effectively
Users may abandon signup if they don’t receive email

Verification Delivery Methods

Users click a link in their email to verify:
Email example:
Features:
  • ✅ Works in all email clients
  • ✅ One-click verification
  • ✅ Longer expiration (default: 3 days)
  • ✅ No typing required
Configuration:
Setting ACCOUNT_CONFIRM_EMAIL_ON_GET = True allows email verification via GET request, which violates HTTP semantics (GET shouldn’t modify state). Only enable if absolutely necessary for compatibility.

Code-Based Verification

Users manually enter a 6-digit code from their email:
Email example:
Features:
  • ✅ Better for mobile users (no link clicking needed)
  • ✅ More secure (session-based, shorter timeout)
  • ✅ Works even if link clicked on different device
  • ⚠️ Requires manual typing
  • ⚠️ Shorter expiration time
Flow: From source (app_settings.py:102-111):

Advanced Verification Features

Change Email During Verification

Allow users to correct their email if they made a typo:
Values:
  • 0 or False - Cannot change email
  • 2 or True - Can change up to 2 times
  • Any integer - Custom limit
Enumeration risk: With enumeration prevention enabled, changing email during verification has limitations. See source (configuration.rst:243-249):
If enumeration prevention is turned on, no account is created when a user signs up using an already existing email. If the user then were able to change to a new email address that is not taken, we would have to create an account as we did not do so yet. Currently, this is not implemented.

Resend Verification Email

Allow users to request a new verification email/code:
Implementation:

Verification Rate Limiting

Prevent abuse of verification email sending: From source (app_settings.py:270-276):
Configuration:
Hard vs. Soft Rate Limiting: From source (flows/email_verification.py:169-187):
Link-based: Rate limit failures are silent (old link still works)
Code-based: Rate limit failures return HTTP 429 (new code needed)

Email Address Model

Model Structure

From source (models.py:20-54):

Key Methods

Mark an email as verified.From source (models.py:75-82):
Checks for conflicts (uniqueness constraint) before verifying.
Set email as primary for the user.From source (models.py:84-99):
Also syncs with User model’s email field.
Send verification email for this address.From source (models.py:101-105):
Delete email and update user model.From source (models.py:107-121):

Manager Methods

Email Confirmation Tokens

HMAC-Based Tokens (Default)

From source (app_settings.py:468-469):
Advantages:
  • Stateless - No database records needed
  • Scalable - No cleanup jobs required
  • Secure - Uses Django’s signing framework
  • Performant - No database queries to verify
From source (configuration.rst:204-209):
In previous versions, a record was stored in the database for each ongoing email confirmation, keeping track of these keys. Current versions use HMAC based keys that do not require server side state.

Database-Based Tokens (Legacy)

Creates EmailConfirmation records: From source (models.py:136-150):
Only needed if you require database records for auditing or have specific compliance requirements.

Verification During Login

Mandatory Verification Blocking

When ACCOUNT_EMAIL_VERIFICATION = "mandatory": From source (flows/email_verification.py:281-308):

Auto-Login After Verification

Log users in automatically after they verify their email:
This only works when:
  1. User is verifying immediately after signup
  2. Browser session is still active
  3. Using link-based verification (not code-based)
Security considerations from source (flows/email_verification.py:108-147):

Custom Verification URLs

Frontend Verification URLs

Redirect to your frontend application for email verification:
The {key} placeholder is replaced with the actual verification token.

Custom URL Construction

Override URL generation in adapter:

Email Templates

Default Templates

django-allauth includes templates for verification emails:

Customizing Email Content

Override templates in your project:

Available Template Context

Variables available in verification email templates:

Programmatic Verification

Verify Email in Code

Indirect Verification

Verify email based on external validation (e.g., OAuth provider):

Redirect After Verification

Configure where users go after verifying their email:
Default behavior:
  • Authenticated: Redirects to LOGIN_REDIRECT_URL
  • Anonymous: Redirects to LOGIN_URL

Signals

Hook into verification events:

Testing Email Verification

Console Email Backend

View emails in console during development:

Disable for Tests

Mock Verification

Best Practices

  • Mandatory: For apps handling sensitive data, financial transactions, or PII
  • Optional: For social apps, content platforms, or when UX is critical
  • None: Only for internal tools or development
If your app is mobile-first, code-based verification provides better UX:
  • No link clicking required
  • Works across devices
  • Users stay in your app
Always allow users to request a new verification email:
Balance security with usability:
  • Link-based: 3 days (users might verify later)
  • Code-based: 15 minutes (active verification flow)
Track verification email delivery and completion rates:

Next Steps

Account Management

Learn about email address management and multiple emails per user

Rate Limiting

Configure rate limits for verification email sending