Django:尝试验证电子邮件验证 OTP 时出错

red*_*sef 1 django django-views python-3.x django-rest-framework

我在注册时向用户发送一封电子邮件,并将 otp 与电子邮件一起获取,我有一个单独的验证模型,如下所示,我面临的错误与{"message": "This OTP is invalid"}verifyEmail 视图中的代码和平有关(在下面)

class Verify(models.Model):
    email = models.EmailField(
        _("Email"), max_length=254, unique=True, default=None, blank=True, null=True)
    otp = IntegerRangeField(
        min_value=111111, max_value=999999, blank=True, null=True)
    created_at = models.DateTimeField(
        _("created at"), auto_now=False, auto_now_add=True, blank=False)
    expires_at = models.DateTimeField(null=True)

    def __str__(self) -> str:
        return self.email
Run Code Online (Sandbox Code Playgroud)

我如何发送电子邮件

def send_opt_email(email, firstname, lastname):
    otp = random.randint(100000, 999999)
    subject = "Email verification"
    message = "Email verification"
    html_message = loader.render_to_string(
        "email_verify.html",
        {
            "firstname": firstname,
            "lastname": lastname,
            "otp": otp,
        },
    )
    email_from = settings.EMAIL_HOST_USER
    send_mail(
        subject,
        message,
        email_from,
        [email],
        fail_silently=True,
        html_message=html_message,
    )
    otp = Verify.objects.create(
        email=email,
        otp=otp,
        created_at=datetime.now(),
        expires_at=datetime.now() + timedelta(minutes=30),
    )
    otp.save()
Run Code Online (Sandbox Code Playgroud)

这是我用来验证 otp 的视图

class Verify_Email(APIView):
    """
    Verify registered emails
    """

    def post(self, request):
        try:
            data = request.data
            serializer = VerifySerializerBase(data=data)
            if serializer.is_valid():
                email = serializer.data["email"]
                otp = serializer.data["otp"]
                verify = Verify.objects.get(email=email)
                user = User.objects.get(email=email)

                try:
                    if user.is_active:
                        return Response(
                            {"message": "This email has already been verified"},
                            status=status.HTTP_400_BAD_REQUEST,
                        )

                    elif verify:
                        print(verify.email)
                        print(verify.otp)
                        print(verify.created_at)
                        print(verify.expires_at)
                        # prints everything as expected
                        now = timezone.now()
                        if verify.otp != otp:
                            return Response(
                                {"message": "This OTP is invalid"},
                                status=status.HTTP_400_BAD_REQUEST,
                            )
                        elif verify.expires_at < now:
                            return Response(
                                {
                                    "message": "This OTP has expired, please request another one"
                                },
                                status=status.HTTP_400_BAD_REQUEST,
                            )
                        verify.delete()
                        user.is_active = True
                        user.save()
                        return Response(
                            {"message": "Email has been verified"},
                            status=status.HTTP_200_OK,
                        )
                except User.DoesNotExist:
                    return Response(
                        {"message": "User was not found"},
                        status=status.HTTP_404_NOT_FOUND,
                    )

                return Response(
                    {"message": "Something is wrong"},
                    status=status.HTTP_400_BAD_REQUEST,
                )

            return Response(
                {"message": "Something is wrong"}, status=status.HTTP_400_BAD_REQUEST
            )

        except Exception as e:
            return Response(
                str(e),
                status=status.HTTP_404_NOT_FOUND,
                template_name=None,
                content_type=None,
            )
Run Code Online (Sandbox Code Playgroud)

我不认为Verify_Email视图是一个很好的实现,任何改进将不胜感激

Sör*_*ifé 6

您是否尝试过对变量进行类型转换?(IE if int(verify.otp) != int(otp):

另外,你百分百确定吗verify.otp == otp?我看到你正在打印,verify.otp但没有otp。两个结果是什么?

  • 当然!如您所知,有不同的数据类型,例如:“int”、“float”、“str”...最有可能发生的情况是在序列化过程中,它将“Verify.otp”从“int”转换为“ `str` 因此您需要将其重新转换为原始数据类型以确保 `otp` 是一个 `int`。 (2认同)