0
0
DjangoHow-ToBeginner · 4 min read

How to Implement Email Verification in Django Easily

To implement email verification in Django, create a user registration view that sends an email with a unique activation token. Use Django's urls and views to handle the activation link, verifying the token and activating the user account.
📐

Syntax

Email verification in Django typically involves these parts:

  • User model: Stores user data and activation status.
  • Token generation: Creates a unique code for email confirmation.
  • Email sending: Sends the activation link to the user's email.
  • Activation view: Checks the token and activates the user.
python
from django.contrib.auth.models import User
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.contrib.auth.tokens import default_token_generator
from django.core.mail import send_mail

# Generate token and uid
uid = urlsafe_base64_encode(force_bytes(user.pk))
token = default_token_generator.make_token(user)

# Activation link example
activation_link = f"http://example.com/activate/{uid}/{token}/"

# Send email
send_mail(
    'Activate your account',
    f'Click here to activate: {activation_link}',
    'from@example.com',
    [user.email],
    fail_silently=False,
)

# In activation view
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
if default_token_generator.check_token(user, token):
    user.is_active = True
    user.save()
💻

Example

This example shows a simple Django view to register a user, send an email verification link, and activate the user when the link is clicked.

python
from django.contrib.auth.models import User
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.core.mail import send_mail
from django.shortcuts import render, redirect
from django.http import HttpResponse

# Registration view

def register(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
        user = User.objects.create_user(username=email, email=email, password=password, is_active=False)
        uid = urlsafe_base64_encode(force_bytes(user.pk))
        token = default_token_generator.make_token(user)
        activation_link = f"http://localhost:8000/activate/{uid}/{token}/"
        send_mail(
            'Activate your account',
            f'Click here to activate your account: {activation_link}',
            'no-reply@example.com',
            [email],
            fail_silently=False,
        )
        return HttpResponse('Please check your email to activate your account.')
    return render(request, 'register.html')

# Activation view

def activate(request, uidb64, token):
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user is not None and default_token_generator.check_token(user, token):
        user.is_active = True
        user.save()
        return HttpResponse('Your account has been activated successfully.')
    else:
        return HttpResponse('Activation link is invalid!')
Output
User receives email with activation link; clicking it activates the account and shows confirmation message.
⚠️

Common Pitfalls

  • Not setting is_active=False on new users allows login before verification.
  • Forgetting to decode uidb64 properly causes errors in activation.
  • Not using Django's default_token_generator can lead to insecure tokens.
  • Failing to handle exceptions when user is not found breaks activation flow.
  • Sending emails without proper SMTP setup causes silent failures.
python
## Wrong: Creating user as active immediately
user = User.objects.create_user(username=email, email=email, password=password, is_active=True)  # Wrong

## Right: Create inactive user
user = User.objects.create_user(username=email, email=email, password=password, is_active=False)  # Correct

## Wrong: Not decoding uidb64
user = User.objects.get(pk=uidb64)  # Wrong

## Right: Decode uidb64
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)  # Correct
📊

Quick Reference

  • Use is_active=False for new users until verified.
  • Generate tokens with default_token_generator.
  • Encode user ID with urlsafe_base64_encode for safe URLs.
  • Send activation link via email with Django's send_mail.
  • Verify token and activate user in the activation view.

Key Takeaways

Always create new users with is_active=False to prevent unverified logins.
Use Django's default_token_generator to create secure activation tokens.
Send an email with a link containing encoded user ID and token for verification.
Decode the user ID and check the token in the activation view to activate the user.
Handle exceptions and email sending errors to ensure smooth verification flow.