使用 Django 的密码重置通知用户电子邮件无效

Posted

技术标签:

【中文标题】使用 Django 的密码重置通知用户电子邮件无效【英文标题】:Inform user that email is invalid using Django's Password Reset 【发布时间】:2015-02-28 07:32:31 【问题描述】:

我正在使用内置的 django 密码重置功能。 The documentation 状态:

如果系统中不存在提供的电子邮件地址,则此视图不会发送电子邮件,但用户也不会收到任何错误消息。这可以防止信息泄露给潜在的攻击者。如果您想在这种情况下提供错误消息,您可以继承 PasswordResetForm 并使用 password_reset_form 参数。

但是,在我的情况下,当用户尝试使用错误的用户名进行重置时显示错误消息更为重要。

我知道我需要做什么,但我不知道在将 PasswordResetForm 子类化的表单中写什么。

PasswordResetForm 的子类化表单应该包含什么?

谢谢。

【问题讨论】:

只需覆盖用户名字段的 clean 方法。 【参考方案1】:

所以我终于自己弄清楚了。这是我的实现:

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

您还需要将'password_reset_form': EmailValidationOnForgotPassword 添加到urls.py。这是一个例子:

url(r'^user/password/reset/$',
    'django.contrib.auth.views.password_reset',
    'post_reset_redirect': '/user/password/reset/done/',
     'html_email_template_name': 'registration/password_reset_email.html',
     'password_reset_form': EmailValidationOnForgotPassword,
    name="password_reset"),

【讨论】:

你可能想要一个不区分大小写的匹配,并且只需要活跃用户:那是表单不发送电子邮件的时候。另外,exists() 会比get() 稍快,所以它会是if not User.objects.filter(email__iexact=email, is_active=True).exists(): raise ValidationError 优秀的观察,谢谢!我已经更新了答案。 这里我在我的代码中提出了 ValidationError 消息,但它不会显示在我的屏幕上 :( 请帮助我。我从 ' from django.core.exceptions import ValidationError '导入 ValidationError 【参考方案2】:

对于更高版本的 Django,例如 Django 2.1,有一个类似的 question,但代码略有修改。

#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('accounts/password_reset/', auth_views.PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='password_reset'),

请注意,这可用于获取用户名/电子邮件。 减少此问题的一种方法是在用户尝试 3 个不同的电子邮件后立即回复 429 Too Many Requests。这可以使用例如django-ratelimit

来实现

【讨论】:

以上是关于使用 Django 的密码重置通知用户电子邮件无效的主要内容,如果未能解决你的问题,请参考以下文章

如果在 django 中重置密码电子邮件链接错误,则找不到页面(404)错误

如何使用 django-rest-auth 和 Mailgun 从 Django 发送密码重置电子邮件

Django Social Auth - 我无法重置通过Facebook签名的用户的密码

如何自定义 django rest auth 密码重置电子邮件内容/模板

WordPress新用户注册时提示“您的密码重设链接无效”

WordPress新用户注册时提示“您的密码重设链接无效”