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

jsl*_*tts 45 passwords django django-authentication

我们有一个Django应用程序,需要特定级别的密码复杂性.我们目前通过客户端JavaScript强制执行此操作,这很容易被适当激励的人击败.

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

EMP*_*EMP 40

我也选择了自定义表格.在urls.py指定自定义表单时:

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

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

  • 对于那些可能不知道@uszywieloryba在谈论什么的人来说,它是用于密码重置的形式.如果你使用这个答案的代码,只需使用`class ValidatingPasswordForm(object):`而不是`class ValidatingPasswordChangeForm(auth.forms.PasswordChangeForm):`.然后定义`class ValidatingPasswordChangeForm(ValidatingPasswordForm,auth.forms.PasswordChangeForm):`和`class ValidatingSetPasswordForm(ValidatingPasswordForm,auth.forms.SetPasswordForm):`,两者都只包含`pass`. (5认同)
  • 不要忘记``django.contrib.auth.forms.SetPasswordForm`` (2认同)

Ces*_*ssa 27

Django 1.9提供内置密码验证,以帮助防止用户使用弱密码.通过修改AUTH_PASSWORD_VALIDATORS项目中的设置来启用它.默认情况下,Django附带以下验证器:

  • UserAttributeSimilarityValidator,它检查密码和用户的一组属性之间的相似性.
  • MinimumLengthValidator,它只是检查密码是否符合最小长度.此验证器配置了自定义选项:它现在要求最小长度为9个字符,而不是默认值8.
  • 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',
    },
]
Run Code Online (Sandbox Code Playgroud)

  • 如果我使用User.objects.create_user()方法通过API创建用户,如何让它在该方法调用上运行密码验证? (5认同)
  • @Collin - 您需要自己调用验证方法,它们不会仅仅因为您将它们放入设置中而自动运行。查看[集成验证](https://docs.djangoproject.com/en/dev/topics/auth/passwords/#integrating-validation)的文档。 (2认同)

Tro*_*eld 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.'))
Run Code Online (Sandbox Code Playgroud)

然后将验证器添加到您要验证的表单字段:

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


Alp*_*per 10

我只是安装django-passwords并让它为你处理:https://github.com/dstufft/django-passwords

之后,您可以简单地对注册表单进行子类化,并使用PasswordField替换该字段.