如何在 Django 中禁用和修改密码验证

How to disable and modify password validation in Django

我希望最终用户在注册时将密码设置为最小和最大长度为 6 个字符的数字 pin。 例如,g:234123 是的,这可能是不安全的,但项目需要使用 6 位密码来完成。 因为 AUTH_PASSWORD_VALIDATORS 不允许这样做。

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',
    },
]

那么如何禁用和修改password validation in Django. Without changing the AUTHENTICATION_BACKENDS 如果我们必须要更改AUTHENTICATION_BACKENDS,那么如何实现呢

已解决。

如何在Django中修改密码验证

config 目录中的 validators.py 中创建了一些验证器,该目录也是 Django 项目名称。

#validators.py
import re
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _

'''
The main purpose of these validators is to accept the password like 6 digit pin only
'''


class LengthValidator:
    def __init__(self, length=6,):
        self.length = length

    def validate(self, password, user=None):
        if len(password) != self.length:
            raise ValidationError(
                _("This password must contain only %(length)d characters."),
                code='password_should_6_digits_pin',
                params={'length': self.length},
            )

    def get_help_text(self):
        return _(
            "Your password must contain only %(length)d characters."
            % {'length': self.length}
        )


class NumberValidator(object):
    def __init__(self, min_digits=6, max_digits=6):
        self.min_digits = min_digits
        self.max_digits = max_digits

    def validate(self, password, user=None):
        if not re.findall('\d{0,10}', password):
            raise ValidationError(
                _("The password must contain only digit between, 0-9. like : 012690"),
                code='only numbers are required',
            )

    def get_help_text(self):
        return _(
            "Your password must contain only digits between, 0-9. like: 012690."
        )


class NoUppercaseValidator(object):
    def validate(self, password, user=None):
        if re.findall('[A-Z]', password):
            raise ValidationError(
                _("The password must not contain uppercase letter, A-Z."),
                code='password_upper',
            )

    def get_help_text(self):
        return _(
            "The password must not contain an uppercase letter, A-Z.",
        )


class NoLowercaseValidator(object):
    def validate(self, password, user=None):
        if re.findall('[a-z]', password):
            raise ValidationError(
                _("The password must not contain lowercase letter, a-z."),
                code='password_no_lower',
            )

    def get_help_text(self):
        return _(
            "Your password must not contain lowercase letters, a-z."
        )


class NoSymbolValidator(object):
    def validate(self, password, user=None):
        if re.findall('[()[\]{}|\`~!@#$%^&*_\-+=;:\'",<>./?]', password):
            raise ValidationError(
                _("The password must not contain any symbol: " +
                  "()[]{}|\`~!@#$%^&*_-+=;:'\",<>./?"),
                code='password_with_symbol',
            )

    def get_help_text(self):
        return _(
            "Your password must not contain any symbol: " +
            "()[]{}|\`~!@#$%^&*_-+=;:'\",<>./?"
        )

将这些导入 settings.py,然后更改 AUTH_PASSWORD_VALIDATORS 至:

AUTH_PASSWORD_VALIDATORS = [

    {'NAME': 'config.validators.LengthValidator', },
    {'NAME': 'config.validators.NumberValidator',
        'OPTIONS': {
            'min_digits': 6,
            'max_digits': 6,
        }},
    {'NAME': 'config.validators.NoUppercaseValidator', },
    {'NAME': 'config.validators.NoLowercaseValidator', },
    {'NAME': 'config.validators.NoSymbolValidator', },
]

就是这样。现在密码只会创建为 6 位密码。

WARNING !!!!!!!!!!! AUTH_PASSWORD_VALIDATORS are now compromised and prone to brute force attack. The Project anatomy was required to use 6 digit pin instead of a Password with 2FA so it was modified.

注意:使用此技术,您还可以创建一个 highly-configurable 验证器来覆盖这些规则 and/or 其他规则,以便根据需要在您的所有项目中重复使用。如果你想要一些强密码。 如果有人需要更多解释。请发表评论。我会更新答案。

您可以使用一个简单的 pin 验证器:

# <em>app_name</em>/password_validation.py

from re import compile as recompile

class PinValidator:
    <strong>pin_regex = recompile('\d{6}')</strong>

    def validate(self, password, user=None):
        if not <strong>self.pin_regex.fullmatch(password)</strong>:
            raise ValidationError(
                _('The password must contain exactly six digit'),
                code='pin_6_digits',
            )

然后将其用作唯一的验证器:

# settings.py

AUTH_PASSWORD_VALIDATORS = [
    {'NAME': <strong>'<em>app_name</em>.password_validation.PinValidator'</strong>, }
]

也就是说,six-digit 密码通常不是一个好的密码:它只有 1'000'000 个项目。如果以后数据库被盗,也很容易通过暴力破解得到密码。