Управление паролями в Django ¶
Управление паролями - это то, что обычно не следует изобретать заново, и Django стремится предоставить безопасный и гибкий набор инструментов для управления паролями пользователей. В этом документе описывается, как Django хранит пароли, как можно настроить хеширование хранилища, а также некоторые утилиты для работы с хешированными паролями.
Смотрите также
Даже если пользователи могут использовать надежные пароли, злоумышленники могут перехватить их соединения. Используйте HTTPS, чтобы избежать отправки паролей (или любых других конфиденциальных данных) по обычным HTTP-соединениям, поскольку они будут уязвимы для перехвата паролей.
Как Django хранит пароли ¶
Django предоставляет гибкую систему хранения паролей и по умолчанию использует PBKDF2.
password
Атрибут
User
объекта является строкой в следующем формате:
<algorithm>$<iterations>$<salt>$<hash>
Это компоненты, используемые для хранения пароля пользователя, разделенные знаком доллара и состоящие из: алгоритма хеширования, количества итераций алгоритма (рабочий коэффициент), случайной соли и результирующего хеша пароля. Алгоритм является одним из множества алгоритмов одностороннего хеширования или хранения паролей, которые может использовать Django; см. ниже. Итерации описывают, сколько раз алгоритм обрабатывает хэш. Соль - это случайное начальное число, а хеш - результат односторонней функции.
По умолчанию Django использует алгоритм PBKDF2 с хешем SHA256, механизм растягивания пароля, рекомендованный NIST . Для большинства пользователей этого должно быть достаточно: это достаточно безопасно, требуя огромного количества вычислительного времени для выхода из строя.
Однако, в зависимости от ваших требований, вы можете выбрать другой алгоритм или даже использовать собственный алгоритм, соответствующий вашей конкретной ситуации безопасности. Опять же, большинству пользователей не нужно этого делать - если вы не уверены, скорее всего, нет. Если да, прочтите:
Django выбирает алгоритм для использования, сверяясь с
PASSWORD_HASHERS
настройками. Это список классов алгоритмов хеширования, которые поддерживает данная установка Django. Первая запись в этом списке (то есть settings.PASSWORD_HASHERS[0]
) будет использоваться для хранения паролей, а все остальные записи - действительные хешеры, которые можно использовать для проверки существующих паролей. Это означает, что если вы хотите использовать другой алгоритм, вам нужно будет внести изменения, PASSWORD_HASHERS
чтобы ваш предпочтительный алгоритм был первым в списке.
По умолчанию PASSWORD_HASHERS
:
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.Argon2PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]
Это означает, что Django будет использовать PBKDF2 для хранения всех паролей, но будет поддерживать проверку паролей, хранящихся с помощью PBKDF2SHA1, argon2 и bcrypt .
В следующих нескольких разделах описываются несколько распространенных способов, которыми опытные пользователи могут захотеть изменить этот параметр.
Использование Argon2 с Django ¶
Argon2 - победитель Конкурса хеширования паролей 2015 года , открытого конкурса, организованного сообществом для выбора алгоритма хеширования следующего поколения. Он спроектирован таким образом, чтобы его не было проще вычислять на специализированном оборудовании, чем на обычном процессоре.
Argon2 не используется по умолчанию для Django, потому что для него требуется сторонняя библиотека. Однако панель Конкурса хеширования паролей рекомендует немедленно использовать Argon2, а не другие алгоритмы, поддерживаемые Django.
Чтобы использовать Argon2 в качестве алгоритма хранения по умолчанию, сделайте следующее:
Установите библиотеку argon2-cffi . Это можно сделать, запустив , что эквивалентно (вместе с любыми требованиями к версии от Django ).
python -m pip install django[argon2]
python -m pip install argon2-cffi
setup.cfg
Измените,
PASSWORD_HASHERS
чтобы список былArgon2PasswordHasher
первым. То есть в вашем файле настроек вы должны указать:PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', ]
Сохраните и / или добавьте любые записи в этот список, если вам нужен Django для обновления паролей .
Использование bcrypt
с Django ¶
Bcrypt - это популярный алгоритм хранения паролей, специально разработанный для длительного хранения паролей. Он не используется по умолчанию в Django, поскольку требует использования сторонних библиотек, но, поскольку многие люди могут захотеть его использовать, Django поддерживает bcrypt с минимальными усилиями.
Чтобы использовать Bcrypt в качестве алгоритма хранения по умолчанию, сделайте следующее:
Установите библиотеку bcrypt . Это можно сделать, запустив , что эквивалентно (вместе с любыми требованиями к версии от Django ).
python -m pip install django[bcrypt]
python -m pip install bcrypt
setup.cfg
Измените,
PASSWORD_HASHERS
чтобы список былBCryptSHA256PasswordHasher
первым. То есть в вашем файле настроек вы должны указать:PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.Argon2PasswordHasher', ]
Сохраните и / или добавьте любые записи в этот список, если вам нужен Django для обновления паролей .
Вот и все - теперь ваша установка Django будет использовать Bcrypt в качестве алгоритма хранения по умолчанию.
Увеличение энтропии соли ¶
Большинство хэшей паролей включают соль вместе с хешами паролей для защиты от атак с использованием радужных таблиц. Сама соль представляет собой случайное значение, которое увеличивает размер и, следовательно, стоимость радужной таблицы, и в настоящее время установлено на 128 бит со salt_entropy
значением в BasePasswordHasher
. По мере уменьшения затрат на вычисления и хранение это значение следует увеличивать. При реализации собственного хэша паролей вы можете переопределить это значение, чтобы использовать желаемый уровень энтропии для хэшей паролей. salt_entropy
измеряется в битах.
Детали реализации
Из-за метода, в котором хранятся значения соли, salt_entropy
фактически это минимальное значение. Например, значение 128 предоставит соль, которая фактически будет содержать 131 бит энтропии.
Увеличение рабочего коэффициента ¶
PBKDF2 и bcrypt ¶
Алгоритмы PBKDF2 и bcrypt используют несколько итераций или раундов хеширования. Это намеренно замедляет злоумышленников, затрудняя атаки на хешированные пароли. Однако по мере увеличения вычислительной мощности количество итераций необходимо увеличивать. Мы выбрали разумное значение по умолчанию (и будем увеличивать его с каждым выпуском Django), но вы можете настроить его вверх или вниз, в зависимости от ваших потребностей в безопасности и доступной вычислительной мощности. Для этого вы создадите подкласс соответствующего алгоритма и переопределите iterations
параметры. Например, чтобы увеличить количество итераций, используемых алгоритмом PBKDF2 по умолчанию:
Создайте подкласс
django.contrib.auth.hashers.PBKDF2PasswordHasher
:from django.contrib.auth.hashers import PBKDF2PasswordHasher class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher): """ A subclass of PBKDF2PasswordHasher that uses 100 times more iterations. """ iterations = PBKDF2PasswordHasher.iterations * 100
Сохраните это где-нибудь в своем проекте. Например, вы можете поместить это в файл типа
myproject/hashers.py
.Добавьте свой новый хешер в качестве первой записи в
PASSWORD_HASHERS
:PASSWORD_HASHERS = [ 'myproject.hashers.MyPBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', ]
Вот и все - теперь ваша установка Django будет использовать больше итераций при хранении паролей с использованием PBKDF2.
Аргон2 ¶
Argon2 имеет три атрибута, которые можно настроить:
time_cost
контролирует количество итераций в хэше.memory_cost
контролирует размер памяти, которая должна использоваться во время вычисления хэша.parallelism
контролирует, на скольких процессорах вычисление хэша может быть распараллелено.
Значения этих атрибутов по умолчанию, вероятно, вам подходят. Если вы определили, что хэш пароля слишком быстрый или слишком медленный, вы можете настроить его следующим образом:
- Выберите
parallelism
количество потоков, которые вы можете сэкономить при вычислении хэша. - Выберите
memory_cost
килобайт памяти, который вы можете сэкономить. - Отрегулируйте
time_cost
и измерьте время, необходимое для хеширования пароля. Выберите то,time_cost
что отнимет у вас приемлемое время. Еслиtime_cost
установлено значение 1, это неприемлемо медленно, нижеmemory_cost
.
memory_cost
интерпретация
Утилита командной строки argon2 и некоторые другие библиотеки интерпретируют
memory_cost
параметр иначе, чем значение, которое использует Django. Преобразование дается .memory_cost == 2 ** memory_cost_commandline
Обновление пароля ¶
Когда пользователи входят в систему, если их пароли хранятся с использованием любого другого алгоритма, кроме предпочтительного, Django автоматически обновит алгоритм до предпочтительного. Это означает, что старые установки Django будут автоматически становиться более безопасными по мере того, как пользователи входят в систему, а также означает, что вы можете переключаться на новые (и более совершенные) алгоритмы хранения по мере их изобретения.
Однако Django может обновлять пароли только с использованием алгоритмов, упомянутых в
PASSWORD_HASHERS
, поэтому при обновлении до новых систем вы должны никогда не удалять записи из этого списка. Если вы это сделаете, пользователи, использующие неупомянутые алгоритмы, не смогут выполнить обновление. Хешированные пароли будут обновляться при увеличении (или уменьшении) количества итераций PBKDF2, раундов bcrypt или атрибутов argon2.
Имейте в виду, что если все пароли в вашей базе данных не закодированы в алгоритме хэширования по умолчанию, вы можете быть уязвимы для атаки по времени перечисления пользователей из-за разницы между продолжительностью запроса входа для пользователя с паролем, закодированным в нестандартный алгоритм и продолжительность запроса входа в систему для несуществующего пользователя (который запускает хешер по умолчанию). Вы можете смягчить это, обновив старые хэши паролей .
Обновление пароля без входа в систему ¶
Если у вас есть база данных со старым и слабым хешем, например MD5 или SHA1, вы можете захотеть обновить эти хеши самостоятельно, вместо того, чтобы ждать обновления, когда пользователь входит в систему (что может никогда не произойти, если пользователь не вернуться на свой сайт). В этом случае вы можете использовать «завернутый» хешер паролей.
В этом примере мы перенесем коллекцию хэшей SHA1 для использования PBKDF2 (SHA1 (пароль)) и добавим соответствующий хеш-пароль для проверки того, ввел ли пользователь правильный пароль при входе в систему. Мы предполагаем, что используем встроенную User
модель и что в нашем проекте есть accounts
приложение. Вы можете изменить шаблон для работы с любым алгоритмом или с пользовательской моделью.
Сначала мы добавим собственный хешер:
from django.contrib.auth.hashers import (
PBKDF2PasswordHasher, SHA1PasswordHasher,
)
class PBKDF2WrappedSHA1PasswordHasher(PBKDF2PasswordHasher):
algorithm = 'pbkdf2_wrapped_sha1'
def encode_sha1_hash(self, sha1_hash, salt, iterations=None):
return super().encode(sha1_hash, salt, iterations)
def encode(self, password, salt, iterations=None):
_, _, sha1_hash = SHA1PasswordHasher().encode(password, salt).split('$', 2)
return self.encode_sha1_hash(sha1_hash, salt, iterations)
Перенос данных может выглядеть примерно так:
from django.db import migrations
from ..hashers import PBKDF2WrappedSHA1PasswordHasher
def forwards_func(apps, schema_editor):
User = apps.get_model('auth', 'User')
users = User.objects.filter(password__startswith='sha1$')
hasher = PBKDF2WrappedSHA1PasswordHasher()
for user in users:
algorithm, salt, sha1_hash = user.password.split('$', 2)
user.password = hasher.encode_sha1_hash(sha1_hash, salt)
user.save(update_fields=['password'])
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
# replace this with the latest migration in contrib.auth
('auth', '####_migration_name'),
]
operations = [
migrations.RunPython(forwards_func),
]
Имейте в виду, что эта миграция займет порядка нескольких минут для нескольких тысяч пользователей, в зависимости от скорости вашего оборудования.
Наконец, мы добавим PASSWORD_HASHERS
настройку:
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'accounts.hashers.PBKDF2WrappedSHA1PasswordHasher',
]
Включите в этот список любые другие хешеры, которые использует ваш сайт.
Включены хешеры ¶
Полный список хешеров, включенных в Django:
[
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.Argon2PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher',
'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
]
Соответствующие названия алгоритмов:
pbkdf2_sha256
pbkdf2_sha1
argon2
bcrypt_sha256
bcrypt
sha1
md5
unsalted_sha1
unsalted_md5
crypt
Написание собственного хешера ¶
Если вы пишете свой собственный хэш-код паролей, который содержит рабочий фактор, такой как количество итераций, вы должны реализовать
метод для преодоления разрыва во время выполнения между рабочим фактором, указанным в пароле, и рабочим фактором по умолчанию для хешера. Это предотвращает временную атаку перечисления пользователей из-за разницы между запросом на вход для пользователя с паролем, закодированным в более раннем количестве итераций, и несуществующим пользователем (который выполняет количество итераций по умолчанию для хешера по умолчанию).harden_runtime(self, password, encoded)
encoded
В качестве примера encoded
возьмем PBKDF2, если он содержит 20 000 итераций, а значение хешера по умолчанию iterations
- 30 000, метод должен password
пройти еще 10 000 итераций PBKDF2.
Если у вашего хешера нет рабочего фактора, реализуйте метод как no-op ( pass
).
Управление паролем пользователя вручную ¶
django.contrib.auth.hashers
Модуль предоставляет набор функций для создания и проверок хэшированных паролей. Вы можете использовать их независимо от User
модели.
-
check_password
( пароль , закодированный ) ¶ Если вы хотите вручную аутентифицировать пользователя, сравнивая обычный текстовый пароль с хешированным паролем в базе данных, используйте удобную функцию
check_password()
. Он принимает два аргумента: пароль в виде обычного текста для проверки и полное значение поля пользователяpassword
в базе данных для проверки и возвращает,True
если они совпадают, вFalse
противном случае.
-
make_password
( пароль , соль = None , hasher = 'default' ) ¶ Создает хешированный пароль в формате, используемом этим приложением. Требуется один обязательный аргумент: пароль в виде обычного текста (строка или байты). При желании вы можете предоставить соль и алгоритм хеширования для использования, если вы не хотите использовать значения по умолчанию (первая запись
PASSWORD_HASHERS
настройки). См. В разделе Включенные хешеры имя алгоритма каждого хешера. Если аргументNone
пароля равен, возвращается непригодный для использования пароль (тот, который никогда не будет принятcheck_password()
).Изменено в Django 3.1:password
Параметр должен быть строкой или байт , если неNone
.
-
is_password_usable
( encoded_password ) ¶ Возвращает,
False
если пароль является результатомUser.set_unusable_password()
.
Проверка пароля ¶
Пользователи часто выбирают плохие пароли. Чтобы помочь смягчить эту проблему, Django предлагает подключаемую проверку пароля. Вы можете настроить несколько валидаторов паролей одновременно. В Django включено несколько валидаторов, но вы также можете написать свои собственные.
Каждый валидатор паролей должен предоставить текст справки, чтобы объяснить требования пользователю, проверить заданный пароль и вернуть сообщение об ошибке, если он не соответствует требованиям, и, при необходимости, получить установленные пароли. Валидаторы также могут иметь дополнительные настройки для точной настройки своего поведения.
Проверка контролируется AUTH_PASSWORD_VALIDATORS
настройкой. По умолчанию для этого параметра используется пустой список, что означает, что валидаторы не применяются. В новых проектах, созданных с использованием startproject
шаблона по умолчанию, по умолчанию включен набор валидаторов.
По умолчанию валидаторы используются в формах для сброса или изменения паролей, а также в командах управления createsuperuser
и changepassword
. Валидаторы не применяются на уровне модели, например, в
User.objects.create_user()
и create_superuser()
, поскольку мы предполагаем, что разработчики, а не пользователи, взаимодействуют с Django на этом уровне, а также потому, что проверка модели не запускается автоматически как часть создания моделей.
Примечание
Проверка пароля может предотвратить использование многих типов слабых паролей. Однако тот факт, что пароль проходит все валидаторы, не гарантирует, что это надежный пароль. Есть много факторов, которые могут ослабить пароль, которые не обнаруживаются даже самыми продвинутыми валидаторами паролей.
Включение проверки пароля ¶
Проверка пароля настраивается в
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',
},
]
Этот пример включает все четыре включенных валидатора:
UserAttributeSimilarityValidator
, который проверяет схожесть пароля и набора атрибутов пользователя.MinimumLengthValidator
, который проверяет, соответствует ли пароль минимальной длине. Этот валидатор настроен с настраиваемым параметром: теперь ему требуется, чтобы минимальная длина составляла девять символов вместо восьми по умолчанию.CommonPasswordValidator
, который проверяет, входит ли пароль в список общих паролей. По умолчанию он сравнивается с включенным списком из 20 000 общих паролей.NumericPasswordValidator
, который проверяет, не является ли пароль полностью числовым.
Для UserAttributeSimilarityValidator
и CommonPasswordValidator
в этом примере мы используем настройки по умолчанию. NumericPasswordValidator
не имеет настроек.
Тексты справки и любые ошибки от валидаторов паролей всегда возвращаются в том порядке, в котором они перечислены AUTH_PASSWORD_VALIDATORS
.
Включены валидаторы ¶
Django включает четыре валидатора:
-
класс
MinimumLengthValidator
( min_length = 8 ) ¶ Проверяет, соответствует ли пароль минимальной длине. Минимальную длину можно настроить с помощью
min_length
параметра.
-
class
UserAttributeSimilarityValidator
( user_attributes = DEFAULT_USER_ATTRIBUTES , max_similarity = 0.7 ) ¶ Проверяет, достаточно ли отличается пароль от определенных атрибутов пользователя.
user_attributes
Параметр должен быть итератора имен атрибутов пользователя , для сравнения. Если этот аргумент не указан, то по умолчанию используется: . Несуществующие атрибуты игнорируются.'username', 'first_name', 'last_name', 'email'
Минимальное подобие отклоненного пароля можно установить по шкале от 0 до 1 с помощью
max_similarity
параметра. Значение 0 отклоняет все пароли, а значение 1 отклоняет только те пароли, которые идентичны значению атрибута.
-
class
CommonPasswordValidator
( password_list_path = DEFAULT_PASSWORD_LIST_PATH ) ¶ Проверяет, не является ли пароль обычным паролем. Это преобразует пароль в нижний регистр (для сравнения без учета регистра) и сравнивает его со списком из 20 000 общих паролей, созданным Ройсом Уильямсом .
password_list_path
Может быть установлен на путь пользовательского файла общих паролей. Этот файл должен содержать по одному паролю в нижнем регистре в каждой строке и может быть простым текстом или сжатым сжатием.
-
класс
NumericPasswordValidator
¶ Проверяет, не является ли пароль полностью числовым.
Интеграция проверки ¶
Есть несколько функций, django.contrib.auth.password_validation
которые вы можете вызывать из собственных форм или другого кода для интеграции проверки пароля. Это может быть полезно, если вы используете пользовательские формы для установки пароля или если у вас есть вызовы API, которые позволяют, например, устанавливать пароли.
-
validate_password
( пароль , пользователь = Нет , password_validators = Нет ) ¶ Проверяет пароль. Если все валидаторы находят пароль действительным, возвращается
None
. Если один или несколько валидаторов отклоняют пароль, выдаетValidationError
все сообщения об ошибках валидаторов.user
Объект не является обязательным: если это не предусмотрено, некоторые валидаторы могут быть не в состоянии выполнить любую проверку и будет принимать любой пароль.
-
password_changed
( пароль , пользователь = Нет , password_validators = Нет ) ¶ Сообщает всем валидаторам, что пароль был изменен. Это может быть использовано валидаторами, например, тем, что предотвращает повторное использование пароля. Это следует вызывать после успешной смены пароля.
Для подклассов
AbstractBaseUser
, поле пароля будет помечено как «грязное» при вызове,set_password()
который вызывает вызовpassword_changed()
после сохранения пользователя.
-
password_validators_help_texts
( password_validators = Нет ) ¶ Возвращает список справочных текстов всех валидаторов. Они объясняют пользователю требования к паролю.
-
password_validators_help_text_html
( password_validators = Нет ) ¶ Возвращает строку HTML со всеми справочными текстами в формате
<ul>
. Это полезно при добавлении проверки пароля в формы, так как вы можете передать вывод непосредственно вhelp_text
параметр поля формы.
-
get_password_validators
( validator_config ) ¶ Возвращает набор объектов валидатора на основе
validator_config
параметра. По умолчанию все функции используют валидаторы, определенные вAUTH_PASSWORD_VALIDATORS
, но, вызывая эту функцию с альтернативным набором валидаторов и затем передавая результат вpassword_validators
параметр других функций, вместо этого будет использоваться ваш собственный набор валидаторов. Это полезно, когда у вас есть типичный набор валидаторов для использования в большинстве сценариев, но также есть особая ситуация, требующая настраиваемого набора. Если вы всегда используете один и тот же набор валидаторов, нет необходимости использовать эту функцию, посколькуAUTH_PASSWORD_VALIDATORS
по умолчанию используется конфигурация из .Структура
validator_config
идентична структуреAUTH_PASSWORD_VALIDATORS
. Возвращаемое значение этой функции может быть передано вpassword_validators
параметр функций, перечисленных выше.
Обратите внимание, что если пароль передается одной из этих функций, это всегда должен быть пароль в виде открытого текста, а не хешированный пароль.
Написание собственного валидатора ¶
Если встроенных валидаторов Django недостаточно, вы можете написать свои собственные валидаторы паролей. Валидаторы имеют довольно небольшой интерфейс. Они должны реализовать два метода:
validate(self, password, user=None)
: проверить пароль. Вернуть,None
если пароль действителен, или вызватьValidationError
сообщение об ошибке, если пароль недействителен. Вы должны уметь справляться сuser
бытиемNone
- если это означает, что ваш валидатор не может работать, возвращайтесьNone
без ошибок.get_help_text()
: предоставить текст справки, чтобы объяснить требования пользователю.
Все элементы в OPTIONS
in AUTH_PASSWORD_VALIDATORS
для вашего валидатора будут переданы конструктору. Все аргументы конструктора должны иметь значение по умолчанию.
Вот базовый пример валидатора с одной необязательной настройкой:
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
class MinimumLengthValidator:
def __init__(self, min_length=8):
self.min_length = min_length
def validate(self, password, user=None):
if len(password) < self.min_length:
raise ValidationError(
_("This password must contain at least %(min_length)d characters."),
code='password_too_short',
params={'min_length': self.min_length},
)
def get_help_text(self):
return _(
"Your password must contain at least %(min_length)d characters."
% {'min_length': self.min_length}
)
Вы также можете реализовать ), который будет вызываться после успешной смены пароля. Это можно использовать, например, для предотвращения повторного использования пароля. Однако, если вы решили сохранить предыдущие пароли пользователя, никогда не следует делать это открытым текстом.password_changed(password, user=None