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

Django验证码异常:提交验证时重复生成新验证码如何解决?

解决Django验证码验证中POST请求重新生成验证码的问题

问题根源很明确:Django的类视图每次HTTP请求都会创建一个全新的View实例。你在__init__方法里初始化的self.code,在GET请求时生成一次,到POST请求时会因为实例重新创建而生成新的验证码,这就导致用户输入的旧验证码和新生成的完全对不上,验证必然失败。

解决方案1:使用Session存储验证码(推荐,适合简单场景)

Session是和用户会话绑定的,跨请求会保留数据,刚好适合存储临时验证码:

@method_decorator(login_required, name='dispatch')
class ConfirmEmail(View):

    def get(self, request):
        email = request.GET.get('email')
        # 在GET请求时生成验证码并存入session
        code = str(random.randint(1000, 9999))
        request.session['confirmation_code'] = code
        
        send_mail(
            "Confirmation Code",
            f"Your confirmation code is: {code}",
            "your-sender-email@example.com",  # 替换为实际发件邮箱
            [email, ])
        return render(request, "views/confirm_email.html")

    def post(self, request):
        confirmation_code = request.POST.get('confirmation_code', '').strip()
        # 从session中取出之前存储的验证码
        stored_code = request.session.get('confirmation_code', '')
        
        if confirmation_code == stored_code:
            # 验证成功后删除session中的验证码,避免重复使用
            del request.session['confirmation_code']
            return redirect('home')
        else:
            return render(request, "views/confirm_email.html", {'error_message': 'Invalid confirmation code'})

解决方案2:使用数据库存储验证码(适合需要有效期管理的场景)

如果需要给验证码设置有效期,或者需要持久化记录,可以将验证码存在用户模型中:

from django.utils import timezone
from datetime import timedelta

@method_decorator(login_required, name='dispatch')
class ConfirmEmail(View):

    def get(self, request):
        email = request.GET.get('email')
        user = request.user
        # 生成验证码并更新用户模型字段
        code = str(random.randint(1000, 9999))
        user.confirmation_code = code
        user.code_expires = timezone.now() + timedelta(minutes=10)  # 设置10分钟有效期
        user.save()
        
        send_mail(
            "Confirmation Code",
            f"Your confirmation code is: {code}",
            "your-sender-email@example.com",
            [email, ])
        return render(request, "views/confirm_email.html")

    def post(self, request):
        confirmation_code = request.POST.get('confirmation_code', '').strip()
        user = request.user
        
        # 验证验证码正确性和有效期
        if (confirmation_code == user.confirmation_code 
            and user.code_expires is not None 
            and user.code_expires > timezone.now()):
            # 验证成功后清空验证码相关字段
            user.confirmation_code = ''
            user.code_expires = None
            user.save()
            return redirect('home')
        else:
            return render(request, "views/confirm_email.html", {'error_message': 'Invalid or expired confirmation code'})

注意:记得删除原来__init__方法里的self.code初始化代码,它已经没用了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:45:10