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

Django项目中邮件验证始终失败问题排查求助

Django邮箱验证流程失败的排查原因

我正在开发一个Django项目,要求用户完成邮箱验证流程。注册时已成功生成并向用户发送验证链接,但调用confirm_email函数进行验证时,每次都失败,跳转至failure.html页面。已确认注册页面生成的OTP与链接中的OTP一致,以下是相关代码:

确认邮箱函数

def confirm_email(request, uidb64, otp):
    try:
        uid = force_bytes(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
        print(user, uid, otp)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user and default_token_generator.check_token(user, otp):
        user.is_active = True
        user.save()
        return render(request, 'path to email_confirmation_success.html')
    else:
        return render(request, 'path to email_confirmation_failure.html')

注册页面函数

def signup_page(req):
    if req.method == 'POST':
        form = CustomUserCreationForm(req.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()

            #Generating otp
            otp = generate_otp(user)
            print(otp)

            #Building email confirmation URL
            cur_site = get_current_site(req)
            # uid = urlsafe_base64_encode(user.pk)
            # otp_encoded = urlsafe_base64_decode(force_bytes(otp))

            confirm_url = f"http://{cur_site.domain}/confirm-email/{(user.pk)}/{otp}/"

            # Load and render the HTML template
            template = loader.get_template('path to confirm-email.html')
            context = {'user': user, 'confirm_url': confirm_url}
            message = template.render(context)

            #Email to be sent
            subject = "Confirm your email"

            #to_email = form.cleaned_data.get('email')
            email = EmailMultiAlternatives(subject, '', to=[user.email])
            email.attach_alternative(message, "text/html")
            email.send()

            return redirect('landing:new')
        
        else:
            form = CustomUserCreationForm()
    return render(req, 'path to signuppage.html', {'form': form})

urls.py配置

from django.contrib import admin
from django.urls import path, include
import sys
sys.path.append("D://OSO//CP Analyzer//cp_analyzer//landing")
from landing import views
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.homepage, name='home'),
    path('landing/', include('landing.urls')),
    path('confirm-email/<str:uidb64>/<str:token>/',views.confirm_email, name='confirmation'),
    path('password-reset/', auth_views.PasswordResetView.as_view(), name='password_reset'),
    path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

可能的失败原因

1. UID编码/解码不匹配

注册页面生成验证链接时,直接使用了原始数字格式的user.pk,但confirm_email函数中却用urlsafe_base64_decode解析uidb64参数。Django的urlsafe_base64_decode要求输入是经过urlsafe_base64_encode编码后的字符串,直接传数字会导致解码错误,进而无法找到对应用户。

修复方式:
注册页面生成URL时,对用户ID进行Base64编码:

uid = urlsafe_base64_encode(force_bytes(user.pk))
confirm_url = f"http://{cur_site.domain}/confirm-email/{uid}/{otp}/"

2. 令牌验证逻辑不兼容

你自定义了generate_otp生成验证码,但验证时却用Django默认的default_token_generator.check_token。默认生成器的令牌是基于用户密码哈希、最后登录时间等字段生成的,和自定义OTP的生成逻辑完全不匹配,必然验证失败。

修复方式:

  • 方案一:实现与generate_otp对应的自定义验证函数,替换default_token_generator.check_token;
  • 方案二:改用Django默认流程,注册时用default_token_generator.make_token(user)生成令牌,验证时用check_token验证。

3. OTP未与用户绑定存储

如果generate_otp生成的是随机码,且没有将其存储到用户模型的字段(如email_otp)中,仅靠默认生成器无法完成验证。此时需要修改验证逻辑,直接对比用户存储的OTP和传入的参数。

4. 视图调试信息缺失

可以通过confirm_email中的print(user, uid, otp)输出排查:

  • 如果user为None,说明UID解码或用户查询失败;
  • 如果user存在但check_token返回False,说明令牌验证逻辑不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:40:20