如何在Django身份验证密码验证器之外使用自定义密码验证器?

13

如上述问题所提及,我将尝试在注册过程中使用某个特定的额外规则来验证密码。

这个额外规则应该是:如果密码至少包含一个数字、一个字母和一个特殊字符,则密码是有效的。

我的解决方法是创建了一个名为 validators.py 的文件。

from django.core.exceptions import ValidationError

class CustomPasswortValidator:

    def validate(value):

      # 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.'))

      # check for special character
      special_characters = "[~\!@#\$%\^&\*\(\)_\+{}\":;'\[\]]"
      if not any(char in special_characters for char in value):
        raise ValidationError(_('Password must contain at least 1 letter.'))

我的自定义注册表单长这样:

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


class RegistrationForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=False,                                         
                                 help_text='Optional.')
    last_name = forms.CharField(max_length=30, required=False, 
                                 help_text='Optional.')
    email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )
我不明白如何告诉Django,让它在使用Django AUTH_PASSWORD_VALIDATORS的同时,也使用我的自定义密码验证器。

我不明白如何告诉Django,让它在使用Django AUTH_PASSWORD_VALIDATORS的同时,也使用我的自定义密码验证器。


你的问题不够清晰。你想使用自定义密码验证器,但又不想在 settings.py 中更改 AUTH_PASSWORD_VALIDATORS 吗?是这样吗? - e4c5
没错,我不想改变 AUTH_PASSWORD_VALIDATORS。 我想创建自己的验证器并将其添加到其他验证器旁边。 - Texas
那个语句并没有澄清事情。 - e4c5
1
"并将其添加到其他验证器旁边。如果您查看AUTH_PASSWORD_VALIDATORS,它是一个列表。您可以自由地在那里添加自己的验证器。" - e4c5
什么?xD 好的,也许我不理解。在 settings.py 中引用了某些验证器。如何添加额外的规则来验证密码? 好的,那么我在上面的文件中所做的是常见的方式吗? - Texas
只需在谷歌上搜索“AUTH_PASSWORD_VALIDATORS”,您就可以看到文档。 - e4c5
1个回答

25

所以,正如e4c5提到的那样,这非常简单明了。

我的CustomPasswordValidator看起来像这样:

from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _

class CustomPasswordValidator():

    def __init__(self, min_length=1):
        self.min_length = min_length

    def validate(self, password, user=None):
        special_characters = "[~\!@#\$%\^&\*\(\)_\+{}\":;'\[\]]"
        if not any(char.isdigit() for char in password):
            raise ValidationError(_('Password must contain at least %(min_length)d digit.') % {'min_length': self.min_length})
        if not any(char.isalpha() for char in password):
            raise ValidationError(_('Password must contain at least %(min_length)d letter.') % {'min_length': self.min_length})
        if not any(char in special_characters for char in password):
            raise ValidationError(_('Password must contain at least %(min_length)d special character.') % {'min_length': self.min_length})

    def get_help_text(self):
        return ""

只需将其添加到 settings.py 中的 AUTH_PASSWORD_VALIDATORS 列表中,就完成了!

AUTH_PASSWORD_VALIDATORS = [
{
    'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
{   'NAME': 'registration.validators.CustomPasswordValidator',

},]

1
你可以接受自己的答案,而且你很可能应该这样做 :-) - e4c5
5
如果我们需要至少一个数字、一个字母和一个特殊字符,那么min_length不应该是3吗? - Rahul Verma
@RahulVerma 不是所有条件的总和,而是每个条件的限制。 - NixonSparrow
我的验证需要用户实例,但我总是得到用户中的None,有什么办法可以将用户传递到验证方法中吗?@Texas?@Nixon? - Adnan Sheikh
@AdnanSheikh 在SO上提问,请不要使用评论。 - NixonSparrow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接