简体   繁体   English

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

[英]Inform user that email is invalid using Django's Password Reset

I am using the built-in django password reset functionality.我正在使用内置的 django 密码重置功能。 The documentation states: 该文档指出:

If the email address provided does not exist in the system, this view won't send an email, but the user won't receive any error message either.如果提供的电子邮件地址在系统中不存在,则此视图不会发送电子邮件,但用户也不会收到任何错误消息。 This prevents information leaking to potential attackers.这可以防止信息泄露给潜在的攻击者。 If you want to provide an error message in this case, you can subclass PasswordResetForm and use the password_reset_form argument.如果您想在这种情况下提供错误消息,您可以继承 PasswordResetForm 并使用 password_reset_form 参数。

However, in my case it's more important to show an error message when a user tries to reset using the wrong username.但是,在我的情况下,当用户尝试使用错误的用户名进行重置时显示错误消息更为重要。

I understand what I need to do but I don't know what to write in the form subclassing PasswordResetForm.我明白我需要做什么,但我不知道在继承 PasswordResetForm 的表单中写什么。

What should the form subclassing PasswordResetForm contain?子类化 PasswordResetForm 的表单应该包含什么?

Thank you.谢谢你。

So I finally figured it out myself. 所以我终于弄明白了。 Here's my implementation: 这是我的实现:

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

You also need to add {'password_reset_form': EmailValidationOnForgotPassword} to urls.py . 您还需要添加{'password_reset_form': EmailValidationOnForgotPassword}urls.py Here's an example: 这是一个例子:

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"),

For later versions of Django such as Django 2.1 there is a similar question with slightly modified code. 对于Django的更高版本,例如Django 2.1,有一个类似的问题 ,略微修改了代码。

#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

And

#urls.py
from accounts.forms import EmailValidationOnForgotPassword

path('accounts/password_reset/', auth_views.PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='password_reset'),

Please be aware that this can be used to obtain usernames/e-mails. 请注意,这可用于获取用户名/电子邮件。 One way to reduce this issue is to respond with a 429 Too Many Requests as soon an user tries 3 different E-Mails. 减少此问题的一种方法是,一旦用户尝试3个不同的电子邮件,就会响应429 Too Many Requests This can be achived using for example django-ratelimit 这可以使用例如django-ratelimit来实现

forms.py表格.py

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

urls.py网址.py

from users.forms import EmailValidationOnForgotPassword
from django.contrib.auth import views as auth_views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('users.urls',namespace='users')),
 
    path('reset_password', auth_views.PasswordResetView.as_view(form_class=EmailValidationOnForgotPassword), name='reset_password'),
    path('reset_password_sent',auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset_password_complete/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

password_reset_form.html password_reset_form.html

 <form method="post">{% csrf_token %}

   {% if form.errors %}
   {% for field in form %}
   {% for error in field.errors %} 
   <div class="alert alert-danger">
      <strong>{{ error|escape }}</strong>
   </div>
   {% endfor %}
   {% endfor %}
   {% endif %} 

   <div class="form-group">
      <label><strong>Email</strong></label>
      {{ form.email|attr:"type:email"|attr:"class:form-control"|attr:"placeholder:Email" }}
   </div>
   <div class="text-center">
      <button type="submit" class="btn btn-primary btn-block">SUBMIT</button>
   </div>
</form>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM