使用django.contrib.auth.views.password_change强制实施密码强度要求

我们有一个Django应用程序需要特定级别的密码复杂性。 我们目前通过客户端JavaScript来执行这个操作,这个JavaScript很容易被适当动机的人打败。

我似乎无法find使用视图中内置的django contrib设置服务器端密码强度validation的任何具体信息。 在我重新发明车轮之前,是否有适当的方法来处理这个要求?

我也用这个自定义的forms。 在urls.py指定您的自定义表单:

 (r'^change_password/$', 'django.contrib.auth.views.password_change', {'password_change_form': ValidatingPasswordChangeForm}), 

PasswordChangeForminheritance并实现validation:

 from django import forms from django.contrib import auth class ValidatingPasswordChangeForm(auth.forms.PasswordChangeForm): MIN_LENGTH = 8 def clean_new_password1(self): password1 = self.cleaned_data.get('new_password1') # At least MIN_LENGTH long if len(password1) < self.MIN_LENGTH: raise forms.ValidationError("The new password must be at least %d characters long." % self.MIN_LENGTH) # At least one letter and one non-letter first_isalpha = password1[0].isalpha() if all(c.isalpha() == first_isalpha for c in password1): raise forms.ValidationError("The new password must contain at least one letter and at least one digit or" \ " punctuation character.") # ... any other validation you want ... return password1 

Django 1.9提供了一个内置的密码validationfunction ,可以防止用户使用弱密码。 通过修改我们的项目中的AUTH_PASSWORD_VALIDATORS设置来启用它。 默认情况下,Django带有以下validation器:

  • UserAttributeSimilarityValidator ,它检查密码和用户的一组属性之间的相似性。
  • MinimumLengthValidator ,它只是检查密码是否满足最小长度。 这个validation器configuration了一个自定义选项:它现在需要的最小长度是九个字符,而不是默认的八个。
  • CommonPasswordValidator ,它检查密码是否出现在普通密码列表中。 默认情况下,它与一个包含1000个常用密码的列表进行比较。
  • NumericPasswordValidator ,它检查密码是否不完全是数字。

这个例子启用了所有四个validation器:

 AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': { 'min_length': 9, } }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] 

我只是安装django密码,让它为您处理: https : //github.com/dstufft/django-passwords

之后,您可以简单地inheritanceregistry单并使用PasswordFieldreplace该字段。

正如一些避免与自定义validation程序,这是我会采取的方法…

创build一个validation器:

 from django.core.exceptions import ValidationError from django.utils.translation import ugettext as _ def validate_password_strength(value): """Validates that a password is as least 7 characters long and has at least 1 digit and 1 letter. """ min_length = 7 if len(value) < min_length: raise ValidationError(_('Password must be at least {0} characters ' 'long.').format(min_length)) # check for digit if not any(char.isdigit() for char in value): raise ValidationError(_('Password must contain at least 1 digit.')) # check for letter if not any(char.isalpha() for char in value): raise ValidationError(_('Password must contain at least 1 letter.')) 

然后将validation器添加到您要validation的表单字段中:

 from django.contrib.auth.forms import SetPasswordForm class MySetPasswordForm(SetPasswordForm): def __init__(self, *args, **kwargs): super(MySetPasswordForm, self).__init__(*args, **kwargs) self.fields['new_password1'].validators.append(validate_password_strength) 

如果您使用表单或为正则expression式编写一些其他脚本检查,我认为您应该编写自己的validation器(或者使用RegexValidator,请参阅: http ://docs.djangoproject.com/zh/dev/ref/validators/)。 这应该是一个简单的任务。 我也不认为有什么内build机制,只是因为每个人都明白“强密码”的概念有点不同。