Управление паролями в 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 в качестве алгоритма хранения по умолчанию, сделайте следующее:

  1. Установите библиотеку argon2-cffi . Это можно сделать, запустив , что эквивалентно (вместе с любыми требованиями к версии от Django ).python -m pip install django[argon2]python -m pip install argon2-cffisetup.cfg

  2. Измените, 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 в качестве алгоритма хранения по умолчанию, сделайте следующее:

  1. Установите библиотеку bcrypt . Это можно сделать, запустив , что эквивалентно (вместе с любыми требованиями к версии от Django ).python -m pip install django[bcrypt]python -m pip install bcryptsetup.cfg

  2. Измените, 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 в качестве алгоритма хранения по умолчанию.

Увеличение энтропии соли

Новое в Django 3.2.

Большинство хэшей паролей включают соль вместе с хешами паролей для защиты от атак с использованием радужных таблиц. Сама соль представляет собой случайное значение, которое увеличивает размер и, следовательно, стоимость радужной таблицы, и в настоящее время установлено на 128 бит со salt_entropyзначением в BasePasswordHasher. По мере уменьшения затрат на вычисления и хранение это значение следует увеличивать. При реализации собственного хэша паролей вы можете переопределить это значение, чтобы использовать желаемый уровень энтропии для хэшей паролей. salt_entropy измеряется в битах.

Детали реализации

Из-за метода, в котором хранятся значения соли, salt_entropy фактически это минимальное значение. Например, значение 128 предоставит соль, которая фактически будет содержать 131 бит энтропии.

Увеличение рабочего коэффициента

PBKDF2 и bcrypt

Алгоритмы PBKDF2 и bcrypt используют несколько итераций или раундов хеширования. Это намеренно замедляет злоумышленников, затрудняя атаки на хешированные пароли. Однако по мере увеличения вычислительной мощности количество итераций необходимо увеличивать. Мы выбрали разумное значение по умолчанию (и будем увеличивать его с каждым выпуском Django), но вы можете настроить его вверх или вниз, в зависимости от ваших потребностей в безопасности и доступной вычислительной мощности. Для этого вы создадите подкласс соответствующего алгоритма и переопределите iterations параметры. Например, чтобы увеличить количество итераций, используемых алгоритмом PBKDF2 по умолчанию:

  1. Создайте подкласс 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.

  2. Добавьте свой новый хешер в качестве первой записи в 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 имеет три атрибута, которые можно настроить:

  1. time_cost контролирует количество итераций в хэше.
  2. memory_cost контролирует размер памяти, которая должна использоваться во время вычисления хэша.
  3. parallelism контролирует, на скольких процессорах вычисление хэша может быть распараллелено.

Значения этих атрибутов по умолчанию, вероятно, вам подходят. Если вы определили, что хэш пароля слишком быстрый или слишком медленный, вы можете настроить его следующим образом:

  1. Выберите parallelismколичество потоков, которые вы можете сэкономить при вычислении хэша.
  2. Выберите memory_costкилобайт памяти, который вы можете сэкономить.
  3. Отрегулируйте 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приложение. Вы можете изменить шаблон для работы с любым алгоритмом или с пользовательской моделью.

Сначала мы добавим собственный хешер:

аккаунты / hashers.py
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)

Перенос данных может выглядеть примерно так:

account / migrations / 0002_migrate_sha1_passwords.py
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настройку:

mysite / settings.py
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параметра.

classUserAttributeSimilarityValidator ( user_attributes = DEFAULT_USER_ATTRIBUTES , max_similarity = 0.7 )

Проверяет, достаточно ли отличается пароль от определенных атрибутов пользователя.

user_attributesПараметр должен быть итератора имен атрибутов пользователя , для сравнения. Если этот аргумент не указан, то по умолчанию используется: . Несуществующие атрибуты игнорируются.'username', 'first_name', 'last_name', 'email'

Минимальное подобие отклоненного пароля можно установить по шкале от 0 до 1 с помощью max_similarityпараметра. Значение 0 отклоняет все пароли, а значение 1 отклоняет только те пароли, которые идентичны значению атрибута.

classCommonPasswordValidator ( 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(): предоставить текст справки, чтобы объяснить требования пользователю.

Все элементы в OPTIONSin 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

Copyright ©2021 All rights reserved