我们有一个Django应用程序需要特定级别的密码复杂性。我们目前通过客户端JavaScript强制执行此操作,这很容易被适当激励的人击败。
我似乎无法找到有关使用视图中内置的django contrib设置服务器端密码强度验证的任何具体信息。在我重新发明轮子之前,是否有正确的方法来处理这个要求?
答案 0 :(得分:40)
我也选择了自定义表单。在urls.py
中指定您的自定义表单:
(r'^change_password/$', 'django.contrib.auth.views.password_change',
{'password_change_form': ValidatingPasswordChangeForm}),
继承PasswordChangeForm
并实施验证:
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
答案 1 :(得分:25)
Django 1.9提供内置password validation,以帮助防止用户使用弱密码。通过修改项目中的AUTH_PASSWORD_VALIDATORS
设置来启用它。默认情况下,Django附带以下验证器:
UserAttributeSimilarityValidator
,检查两者之间的相似性
密码和用户的一组属性。MinimumLengthValidator
,它只是检查密码
满足最小长度。此验证程序配置了自定义
选项:现在要求最小长度为9个字符,
而不是默认的八。CommonPasswordValidator
,检查
密码是否出现在常用密码列表中。通过
默认情况下,它与包含的1000个常用密码列表进行比较。NumericPasswordValidator
,用于检查密码是否存在
完全是数字。此示例启用所有四个包含的验证器:
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',
},
]
答案 2 :(得分:14)
正如一些人对自定义验证器所说的那样,这是我采取的方法......
创建验证器:
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.'))
然后将验证器添加到您要验证的表单字段中:
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)
答案 3 :(得分:10)
我只是安装django-passwords并让它为你处理:https://github.com/dstufft/django-passwords
之后,您可以简单地对注册表单进行子类化,并使用PasswordField替换该字段。
答案 4 :(得分:2)
我认为你应该编写自己的验证器(或者使用RegexValidator,参见:http://docs.djangoproject.com/en/dev/ref/validators/),如果你使用表单或者写一些其他脚本检查正则表达式。这应该是一项简单的任务。另外我不认为有任何内置机制,只是因为每个人都理解“强密码”的概念有点不同。