Django密码重置表单邮件验证

3

Django的password_reset表单不会检查电子邮件是否存在。无论给定的电子邮件地址是什么,它都会验证表单。

问题是,如何使用自定义表单检查并抛出不存在的电子邮件错误?

顺便说一下,我在这里找到了以下解决方案,但对我没有用(使用Django 2.1)。如果这应该起作用,我找不到我缺少什么。

forms.py

class EmailValidationOnForgotPassword(PasswordResetForm):
def clean_email(self):
    email = self.cleaned_data['email']
    if not User.objects.filter(email__iexact=email, is_active=True).exists():
        raise ValidationError("There is no user registered with the specified email address!")

    return email

urls.py

path('sifre-sifirla/', PasswordResetView.as_view(), {'password_reset_form':EmailValidationOnForgotPassword}, name='password_reset'),

提前感谢您。

编辑:

为了其他用户的信息,问题已由@Alasdair回答并且有效,但@pypypy的观点也很重要。

urls.py中的更改如下:

path('sifre-sifirla/', PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='password_reset'),

1
通常情况下,您不希望显示电子邮件不存在的错误,因为这可能会被用作用户枚举安全漏洞。 - pypypy
是的,你说得对!因此,在password_reset_done.html中添加一些信息,例如“如果您没有收到电子邮件,则可以输入另一个电子邮件地址”,将解决问题。顺便问一下,我想知道未来的解决方案。无论如何,谢谢。@pypypy - Sarp
1
对于 PasswordResetView,属性应该是 form_class 而不是 password_reset_form。我会删除字典并将其作为参数传递给 as_view()path('sifre-sifirla/', PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='password_reset') - Alasdair
1
@Alasdair,谢谢你的回复,它现在可以工作了。但是pypypy的观点也很重要对我来说。现在我有了做事情的线索。再次感谢。 - Sarp
是的,你需要考虑是否透露账户存在是可接受的。但请记住,你可能已经在其他地方透露了它。例如,你的注册页面可能会显示错误信息“该电子邮件已有账户存在”。 - Alasdair
@Alasdair 确实是使用的最佳场所。 - Sarp
1个回答

1

总结以上讨论,部分内容摘自@Alasdair的发言

#forms.py
from django.contrib.auth.forms import PasswordResetForm

class EmailValidationOnForgotPassword(PasswordResetForm):

    def clean_email(self):
        email = self.cleaned_data['email']
        if not User.objects.filter(email__iexact=email, is_active=True).exists():
            msg = _("There is no user registered with the specified E-Mail address.")
            self.add_error('email', msg)
        return email

并且

#urls.py
from accounts.forms import EmailValidationOnForgotPassword

path('sifre-sifirla/', PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='password_reset'),

@pypypy说得没错,这种方法可以用来获取用户名。减少这个问题的一种方法是,在用户尝试使用3个不同的电子邮件时立即响应429 Too Many Requests。例如,可以使用django-ratelimit实现这个目标。


感谢分享答案 :) - Rayees AC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接