You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django注册页面添加邮箱验证功能需求咨询(含代码片段)

Alright, let's walk through adding email verification to your Django signup flow step by step. I'll cover everything from extending the user model to sending verification emails and handling token validation—no third-party packages required (unless you want to use them later!).


Step 1: Extend the User Model with Verification Fields

First, we need to track whether a user's email is verified and store a secure verification token. We'll use a UserProfile model linked to Django's default User via a one-to-one relationship (skip this if you're already using a custom user model):

# your_app/models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    is_email_verified = models.BooleanField(default=False)
    verification_token = models.CharField(max_length=200, blank=True)

# Auto-create a profile whenever a new User is created
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.userprofile.save()

Step 2: Create Token Utilities

Use Django's built-in signing module to generate tamper-proof, time-limited tokens (this is more secure than storing random strings without expiration):

# your_app/utils.py
from django.core.signing import TimestampSigner, BadSignature, SignatureExpired

def generate_verification_token(user):
    # Adds a timestamp to the token so we can enforce expiration
    signer = TimestampSigner()
    return signer.sign(user.id)

def verify_verification_token(token, max_age=86400):
    # Token expires after 24 hours (86400 seconds)
    signer = TimestampSigner()
    try:
        user_id = signer.unsign(token, max_age=max_age)
        return user_id
    except (BadSignature, SignatureExpired):
        return None

Step 3: Modify the Signup View

Update your signup view to create a non-active user (so they can't log in until verified), generate a token, and send the verification email:

# your_app/views.py
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.core.mail import send_mail
from django.conf import settings
from django.contrib import messages
from .models import UserProfile
from .utils import generate_verification_token

def signup(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        email = request.POST.get('email')
        password = request.POST.get('password')

        # Basic validation (add more as needed)
        if User.objects.filter(username=username).exists():
            messages.error(request, 'Username already taken.')
            return redirect('signup')
        if User.objects.filter(email=email).exists():
            messages.error(request, 'Email already registered.')
            return redirect('signup')

        # Create user but keep them inactive
        user = User.objects.create_user(
            username=username,
            email=email,
            password=password
        )
        user.is_active = False
        user.save()

        # Generate token and update profile
        token = generate_verification_token(user)
        profile = UserProfile.objects.get(user=user)
        profile.verification_token = token
        profile.save()

        # Build the verification URL
        verification_url = f"{request.scheme}://{request.get_host()}/verify-email/{token}/"

        # Send the verification email
        subject = 'Verify Your Email for Our App'
        message = f"""Hi {username},

Thanks for signing up! Please click the link below to verify your email address:

{verification_url}

This link will expire in 24 hours. If you didn't create an account with us, feel free to ignore this email.

Best regards,
The Team
"""
        send_mail(
            subject,
            message,
            settings.DEFAULT_FROM_EMAIL,
            [email],
            fail_silently=False,
        )

        return render(request, 'fir/verification_sent.html')

    # GET request: render the signup form
    return render(request, 'fir/signup.html')

Step 4: Create the Verification View

This view will validate the token, activate the user, and mark their email as verified:

# your_app/views.py (add this function)
from .utils import verify_verification_token

def verify_email(request, token):
    user_id = verify_verification_token(token)
    if not user_id:
        messages.error(request, 'Invalid or expired verification link. Please request a new one.')
        return redirect('signup')

    try:
        user = User.objects.get(id=user_id)
        profile = UserProfile.objects.get(user=user)
    except (User.DoesNotExist, UserProfile.DoesNotExist):
        messages.error(request, 'User not found.')
        return redirect('signup')

    if profile.is_email_verified:
        messages.info(request, 'Your email is already verified. You can log in now.')
        return redirect('login')

    # Activate the user and mark email as verified
    user.is_active = True
    profile.is_email_verified = True
    user.save()
    profile.save()

    messages.success(request, 'Email verified successfully! You can now log in.')
    return redirect('login')

Step 5: Update Your URLs

Add the verification endpoint to your app's urls.py:

# your_app/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('verify-email/<str:token>/', views.verify_email, name='verify_email'),
    # Add your login URL here if it's not already present
    path('login/', views.login_view, name='login'),
]

Step 6: Create the "Verification Sent" Template

Make a simple template to confirm the email was sent to the user:

<!-- fir/verification_sent.html -->
{% extends 'fir/base_visitor.html' %}
{% block title %}Verification Sent{% endblock %}
{% block body %}
<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="col-sm-12 col-md-6">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">Check Your Email</h3>
                </div>
                <div class="panel-body">
                    <p>We've sent a verification link to <strong>{{ request.POST.email }}</strong>. Please click it to complete your registration.</p>
                    <p>If you don't see the email within a few minutes, check your spam or junk folder.</p>
                    <a href="{% url 'signup' %}" class="btn btn-default">Back to Signup</a>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Step 7: Configure Email Settings

In your settings.py, set up the email backend to send emails. For example, using Gmail (use an app password if 2FA is enabled):

# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-email@gmail.com'
EMAIL_HOST_PASSWORD = 'your-app-password-or-email-password'
DEFAULT_FROM_EMAIL = 'your-email@gmail.com'

Bonus: Add a "Resend Verification" Feature

If users don't get the email, add a view to resend the verification link:

# views.py
def resend_verification(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        try:
            user = User.objects.get(email=email, is_active=False)
            profile = UserProfile.objects.get(user=user)
            token = generate_verification_token(user)
            profile.verification_token = token
            profile.save()

            verification_url = f"{request.scheme}://{request.get_host()}/verify-email/{token}/"
            subject = 'Resend: Verify Your Email Address'
            message = f"""Hi {user.username},

Here's your new verification link:

{verification_url}

This link expires in 24 hours.

Best regards,
The Team
"""
            send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email])
            messages.success(request, 'New verification link sent to your email.')
            return redirect('resend_verification')
        except User.DoesNotExist:
            messages.error(request, 'No inactive account found with this email.')
            return redirect('resend_verification')
    return render(request, 'fir/resend_verification.html')

Just add a corresponding template and URL for this view, and you're set!

内容的提问来源于stack exchange,提问作者Afreen Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:11:13