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

Vla*_*zki 12 django django-forms django-authentication

我正在使用内置的django密码重置功能.文件说明:

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

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

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

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

谢谢.

Vla*_*zki 19

所以我终于弄明白了.这是我的实现:

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
Run Code Online (Sandbox Code Playgroud)

您还需要添加{'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"),
Run Code Online (Sandbox Code Playgroud)

  • 您可能需要不区分大小写的匹配,仅限活动用户:表单不发送电子邮件时.另外,`exists()`会比`get()`略快,所以如果不是User.objects.filter(email__iexact = email,is_active = True).exists():raise ValidationError` (3认同)

ohl*_*hlr 5

对于 Django 2.1 等更高版本的 Django,有一个类似的问题,代码稍有修改。

#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
Run Code Online (Sandbox Code Playgroud)

#urls.py
from accounts.forms import EmailValidationOnForgotPassword

path('accounts/password_reset/', auth_views.PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='password_reset'),
Run Code Online (Sandbox Code Playgroud)

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