Python Django密码重置:新密码必须不同于用户提交的最后四个密码中的任何一个
我是Django新手,请帮助我如何实现密码重置,以便新密码必须不同于用户在Django中提交的最后四个密码中的任何一个: 我正在使用默认的django密码重置: URL.py: django/contrib/auth/views.py:Python Django密码重置:新密码必须不同于用户提交的最后四个密码中的任何一个,python,django,security,Python,Django,Security,我是Django新手,请帮助我如何实现密码重置,以便新密码必须不同于用户在Django中提交的最后四个密码中的任何一个: 我正在使用默认的django密码重置: URL.py: django/contrib/auth/views.py: @csrf_protect def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.h
@csrf_protect
def password_reset(request, is_admin_site=False,
template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html',
subject_template_name='registration/password_reset_subject.txt',
password_reset_form=PasswordResetForm,
token_generator=default_token_generator,
post_reset_redirect=None,
from_email=None,
current_app=None,
extra_context=None):
if post_reset_redirect is None:
post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')
if request.method == "POST":
form = password_reset_form(request.POST)
if form.is_valid():
opts = {
'use_https': request.is_secure(),
'token_generator': token_generator,
'from_email': from_email,
'email_template_name': email_template_name,
'subject_template_name': subject_template_name,
'request': request,
}
if is_admin_site:
opts = dict(opts, domain_override=request.get_host())
form.save(**opts)
return HttpResponseRedirect(post_reset_redirect)
else:
form = password_reset_form()
context = {
'form': form,
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
我是否应该创建数据库表来存储用户以前的所有密码,或者是否有任何django库可以为我提供此功能。是的,您可以创建一个模型,并在密码重置/更改时存储用户的所有密码
from django.contrib.auth.models import User
import json
class OldPasswords(models.Model):
user = model.ForeignKey(User)
pwd = models.CharField(max_length=200)
def setPasswords(self, pwd):
self.pwd = json.dumps(pwd)
def getPasswords(self):
return json.loads(self.pwd)
在密码重置/更改时创建一个信号并保存当前密码
例如:
from allauth.account.signals import password_changed, password_reset
def send_password_changed_email(sender, **kwargs):
user = kwargs.get('user')
if user:
pwds = OldPasswords.objects.get_or_create(user=user)
pwds.setPasswords(pwd)
保存到模型后,您需要实现自定义验证器,以便在用户在重置时尝试旧密码时显示验证消息:
- 验证(self,password,user=None):验证密码。如果密码有效,则返回None,或者使用 如果密码无效,则显示错误消息。你必须能够 处理用户为无-如果这意味着您的验证器无法运行, 只需返回None,就不会有错误
- get_help_text():提供帮助文本向用户解释需求
from django.core.exceptions import ValidationError
from yourapp.model import OldPasswords
from django.utils.translation import ugettext as _
class PasswordValidator(object):
def __init__(self, password):
self.password = password
def validate(self, password, user=None):
pwd_list = OldPasswords.objects.get(user=user).getPasswords()
if password in pwd_list:
raise ValidationError(
_("You used this password recently. Please choose a different one."),
code='password_recently_used',
params={'min_length': self.min_length},
)
def get_help_text(self):
return _(
"You used this password recently. Please choose a different one."
)
但是,如果您决定存储用户以前的密码,则不应以明文形式存储。谢谢您提供的详细答案。请帮助我如何在我的pass_reset视图或模板中使用PasswordValidator。密码验证是在AUTH_Password_VALIDATORS设置中配置的:
AUTH_Password_VALIDATORS=[{'NAME':'django.contrib.AUTH.Password_validation.UserAttributesMilarityValidator',},]
from django.core.exceptions import ValidationError
from yourapp.model import OldPasswords
from django.utils.translation import ugettext as _
class PasswordValidator(object):
def __init__(self, password):
self.password = password
def validate(self, password, user=None):
pwd_list = OldPasswords.objects.get(user=user).getPasswords()
if password in pwd_list:
raise ValidationError(
_("You used this password recently. Please choose a different one."),
code='password_recently_used',
params={'min_length': self.min_length},
)
def get_help_text(self):
return _(
"You used this password recently. Please choose a different one."
)