Как отключить и изменить проверку пароля в Django
Я хочу, чтобы конечный пользователь при регистрации задавал пароль в виде цифрового пина длиной минимум & максимум 6 символов.
Например: 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',
},
]
Итак, как отключить и изменить валидацию пароля в Django. Без изменения AUTHENTICATION_BACKENDS Если нам придется изменить AUTHENTICATION_BACKENDS
, то как этого добиться.
Решено.
Как изменить проверку пароля в Django
Создал несколько валидаторов в validators.py в дире config
, который также является именем проекта 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 digit 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 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-значный пин-код.
ПРЕДУПРЕЖДЕНИЕ !!!!!!!!!!!
.AUTH_PASSWORD_VALIDATORS
теперь скомпрометированы и подвержены атаке грубой силы и многие. Проект анатомии был требовалось использовать 6-значный пин-код вместо пароля, поэтому он был изменен.
Примечание: Используя эту технику, вы также можете создать единый, высококонфигурируемый валидатор, охватывающий эти правила и/или другие, чтобы использовать его во всех ваших проектах по мере необходимости. если вам нужны надежные пароли. Если кому-то нужно больше объяснений, просто оставьте комментарий. Я обновлю ответ.
Вы можете работать с простым валидатором для пина:
# app_name/password_validation.py
from re import compile as recompile
class PinValidator:
pin_regex = recompile('\d{6}')
def validate(self, password, user=None):
if not self.pin_regex.fullmatch(password):
raise ValidationError(
_("The password must contain exactly six digit'),
code='pin_6_digits',
)
и затем использовать это как единственный валидатор:
# settings.py
AUTH_PASSWORD_VALIDATORS = [
{'NAME': 'app_name.password_validation.PinValidator', }
]
При этом шестизначный пин-код обычно не является хорошим паролем: он имеет всего 1'000'000 элементов. Если впоследствии база данных будет украдена, то PIN-коды также очень легко получить методом перебора.