Spec-Zone.ru › Django 5.1

Управление паролями в Django

Управление паролями — это то, что обычно не следует изобретать заново, и Django стремится предоставить безопасный и гибкий набор инструментов для управления паролями пользователей. Этот документ описывает, как Django хранит пароли, как можно настроить хэширование хранения и некоторые утилиты для работы с хэшированными паролями.

См. также

Даже если пользователи используют сложные пароли, злоумышленники могут перехватывать их подключения. Используйте HTTPS, чтобы избежать отправки паролей (или любых других конфиденциальных данных) по обычным HTTP-соединениям, поскольку они будут уязвимы для перехвата паролей.

Как Django хранит пароли

Django предоставляет гибкую систему хранения паролей и использует PBKDF2 по умолчанию.

Атрибут password объекта User — это строка в этом формате:

<algorithm>$<iterations>$<salt>$<hash>

Это компоненты, используемые для хранения пароля пользователя, разделенные символом «доллар» и состоят из: алгоритма хэширования, числа итераций алгоритма (фактора сложности), случайной соли и получившегося хэша пароля. Алгоритм — один из ряда односторонних алгоритмов хэширования или хранения паролей, которые может использовать Django; см. ниже. Итерации описывают число раз, когда алгоритм выполняется над хэшем. Соль — это случайное начальное значение, а хэш — результат односторонней функции.

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

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

Django выбирает используемый алгоритм, обращаясь к настройке PASSWORD_HASHERS. Это список классов алгоритмов хэширования, которые поддерживает данная установка Django.

Для хранения паролей Django будет использовать первый хэшировщик в PASSWORD_HASHERS. Чтобы сохранить новые пароли с другим алгоритмом, поместите предпочтительный алгоритм в начале списка PASSWORD_HASHERS.

Для проверки паролей Django найдет хэшировщик в списке, который соответствует имени алгоритма в хранящемся пароле. Если хранящийся пароль называет алгоритм, не найденный в PASSWORD_HASHERS, попытка его проверки вызовет ValueError.

Значение по умолчанию для 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.contrib.auth.hashers.ScryptPasswordHasher",
]

Это означает, что Django будет использовать PBKDF2 для хранения всех паролей, но будет поддерживать проверку паролей, хранящихся с PBKDF2SHA1, argon2 и bcrypt.

В следующих разделах описаны несколько распространенных способов, которыми продвинутые пользователи могут изменить это значение.

Использование Argon2 с Django

Argon2 — победитель конкурса 2015 года по хэшированию паролей Password Hashing Competition, организованного сообществом для выбора алгоритма хэширования следующего поколения. Он разработан таким образом, чтобы не быть проще для вычисления на специализированном оборудовании, чем на обычном процессоре. По умолчанию для хэшировщика паролей Argon2 используется вариант Argon2id.

Argon2 не является стандартным для Django, так как он требует сторонней библиотеки. Однако панель конкурса по хэшированию паролей рекомендует немедленное использование Argon2, а не других поддерживаемых Django алгоритмов.

Чтобы использовать Argon2id в качестве стандартного алгоритма хранения, выполните следующие действия:

  1. Установите пакет argon2-cffi. Это можно сделать, выполнив python -m pip install django[argon2], что эквивалентно python -m pip install argon2-cffi (вместе с любыми требованиями к версии из pyproject.toml Django).
  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.contrib.auth.hashers.ScryptPasswordHasher",
    ]
    

    Сохраните и/или добавьте любые записи в этом списке, если вам нужно, чтобы Django обновлял пароли.

Использование bcrypt с Django

Bcrypt — популярный алгоритм хранения паролей, специально разработанный для долгосрочного хранения паролей. Он не является стандартным для Django, поскольку требует использования сторонних библиотек, но, поскольку многие пользователи могут захотеть его использовать, Django поддерживает bcrypt с минимальными усилиями.

Чтобы использовать Bcrypt в качестве стандартного алгоритма хранения, выполните следующие действия:

  1. Установите пакет bcrypt. Это можно сделать, выполнив python -m pip install django[bcrypt], что эквивалентно python -m pip install bcrypt (вместе с любыми требованиями к версии из pyproject.toml Django).
  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.contrib.auth.hashers.ScryptPasswordHasher",
    ]
    

    Сохраните и/или добавьте любые записи в этом списке, если вам нужно, чтобы Django обновлял пароли.

Всё готово — теперь ваша установка Django будет использовать Bcrypt в качестве стандартного алгоритма хранения.

Использование scrypt с Django

Scrypt похож на PBKDF2 и bcrypt в использовании определенного числа итераций для замедления атак методом перебора. Однако, поскольку PBKDF2 и bcrypt не требуют много памяти, злоумышленники с достаточными ресурсами могут запускать масштабные параллельные атаки, чтобы ускорить процесс атаки. Scrypt специально разработан для использования большего объема памяти по сравнению с другими функциями вывода ключей на основе паролей, чтобы ограничить количество параллелизма, которое может использовать злоумышленник, см. RFC 7914 для получения дополнительной информации.

Чтобы использовать scrypt в качестве стандартного алгоритма хранения, выполните следующие действия:

  1. Измените PASSWORD_HASHERS, чтобы в начале списка был ScryptPasswordHasher. То есть в вашем файле настроек:

    PASSWORD_HASHERS = [
        "django.contrib.auth.hashers.ScryptPasswordHasher",
        "django.contrib.auth.hashers.PBKDF2PasswordHasher",
        "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
        "django.contrib.auth.hashers.Argon2PasswordHasher",
        "django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
    ]
    

    Сохраните и/или добавьте любые записи в этом списке, если вам нужно, чтобы Django обновлял пароли.

Примечание

scrypt требует OpenSSL 1.1+.

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

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

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

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

Увеличение фактора сложности алгоритма

PBKDF2 и bcrypt

Алгоритмы PBKDF2 и bcrypt используют число итераций или раундов хэширования. Это преднамеренно замедляет злоумышленников, затрудняя атаки на хэшированные пароли. Однако по мере увеличения вычислительной мощности число итераций необходимо увеличивать. Мы выбрали разумное значение по умолчанию (и будем увеличивать его с каждым выпуском Django), но вы можете настроить его вверх или вниз в зависимости от ваших потребностей в безопасности и доступной вычислительной мощности. Для этого вы создадите подкласс соответствующего алгоритма и переопределите параметр iterations (используйте параметр rounds при создании подкласса хэшировщика bcrypt). Например, чтобы увеличить число итераций, используемых стандартным алгоритмом 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.contrib.auth.hashers.ScryptPasswordHasher",
    ]
    

Всё готово — теперь ваша установка Django будет использовать больше итераций при хранении паролей с помощью PBKDF2.

Примечание

bcrypt rounds — это логарифмический фактор сложности, например, 12 раундов означают 2 ** 12 итераций.

Argon2

У 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.

scrypt

scrypt имеет следующие атрибуты, которые можно настроить:

  1. work_factor управляет количеством итераций внутри хеша.
  2. block_size
  3. parallelism управляет количеством потоков, которые будут выполняться параллельно.
  4. maxmem ограничивает максимальный размер памяти, который можно использовать во время вычисления хеша. По умолчанию 0, что означает ограничение по умолчанию из библиотеки OpenSSL.

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

Оценивание потребления памяти

Минимальное потребление памяти у scrypt составляет:

work_factor * 2 * block_size * 64

поэтому вам может потребоваться настроить maxmem, при изменении значений work_factor или block_size.

Обновление паролей

При входе пользователей, если их пароли хранятся с любым алгоритмом, отличным от предпочтительного, Django автоматически обновит алгоритм до предпочтительного. Это означает, что старые установки Django будут автоматически становиться более безопасными по мере входа пользователей, а также означает, что вы можете переключиться на новые (и лучшие) алгоритмы хранения по мере их появления.

Однако, Django может обновлять только пароли, которые используют алгоритмы, упомянутые в PASSWORD_HASHERS, поэтому при обновлении до новых систем вы должны убедиться, что никогда не удаляете записи из этого списка. Если вы это сделаете, пользователи, использующие неуказанные алгоритмы, не смогут обновить свои пароли. Хешированные пароли будут обновляться при увеличении (или уменьшении) количества итераций PBKDF2, раундов bcrypt или атрибутов argon2.

Помните, что если все пароли в вашей базе данных не закодированы с помощью алгоритма хеширования по умолчанию, вы можете быть уязвимы для атаки перечисления пользователей по времени из-за разницы во времени выполнения запроса входа для пользователя с паролем, закодированным в алгоритме, отличном от алгоритма по умолчанию, и времени выполнения запроса входа для несуществующего пользователя (который использует хешер по умолчанию). Вы можете смягчить это, выполнив обновление старых хешей паролей.

Обновление паролей без требования входа

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

В этом примере мы переведём набор хешей MD5 на использование PBKDF2(MD5(пароль)) и добавим соответствующий хешер паролей для проверки правильности введённого пользователем пароля при входе. Мы предполагаем, что мы используем встроенную User модель и что наш проект имеет accounts приложение. Вы можете изменить шаблон, чтобы он работал с любым алгоритмом или пользовательской моделью.

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

accounts/hashers.py
from django.contrib.auth.hashers import (
    PBKDF2PasswordHasher,
    MD5PasswordHasher,
)


class PBKDF2WrappedMD5PasswordHasher(PBKDF2PasswordHasher):
    algorithm = "pbkdf2_wrapped_md5"

    def encode_md5_hash(self, md5_hash, salt, iterations=None):
        return super().encode(md5_hash, salt, iterations)

    def encode(self, password, salt, iterations=None):
        _, _, md5_hash = MD5PasswordHasher().encode(password, salt).split("$", 2)
        return self.encode_md5_hash(md5_hash, salt, iterations)

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

accounts/migrations/0002_migrate_md5_passwords.py
from django.db import migrations

from ..hashers import PBKDF2WrappedMD5PasswordHasher


def forwards_func(apps, schema_editor):
    User = apps.get_model("auth", "User")
    users = User.objects.filter(password__startswith="md5$")
    hasher = PBKDF2WrappedMD5PasswordHasher()
    for user in users:
        algorithm, salt, md5_hash = user.password.split("$", 2)
        user.password = hasher.encode_md5_hash(md5_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.PBKDF2WrappedMD5PasswordHasher",
]

Включите в этот список все другие хешеры, которые использует ваш сайт.

Включённые хешеры

Полный список хешеров, включённых в 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.ScryptPasswordHasher",
    "django.contrib.auth.hashers.MD5PasswordHasher",
]

Соответствующие имена алгоритмов:

  • pbkdf2_sha256
  • pbkdf2_sha1
  • argon2
  • bcrypt_sha256
  • bcrypt
  • scrypt
  • md5

Написание собственного хешера паролей

Если вы пишете свой собственный хешер паролей, который содержит множитель сложности, такой как количество итераций, вы должны реализовать метод harden_runtime(self, password, encoded), чтобы устранить разрыв во времени выполнения между множителем сложности, заданным в encoded паролем, и множителем сложности по умолчанию хешера. Это предотвращает атаки перечисления пользователей по времени из-за разницы во времени выполнения запроса входа для пользователя с паролем, закодированным в старом множителе сложности, и несуществующего пользователя (который использует множитель сложности по умолчанию хешера по умолчанию).

Принимая PBKDF2 в качестве примера, если encoded содержит 20 000 итераций, а множитель сложности по умолчанию хешера iterations равен 30 000, метод должен выполнить password ещё 10 000 итераций PBKDF2.

Если ваш хешер не имеет множителя сложности, реализуйте метод как no-op (pass).

Ручная обработка пароля пользователя

Модуль django.contrib.auth.hashers предоставляет набор функций для создания и проверки хешированных паролей. Вы можете использовать их независимо от User модели.

check_password(password, encoded, setter=None, preferred='default') [source]
acheck_password(password, encoded, asetter=None, preferred='default')

Асинхронная версия: acheck_password()

Если вы хотите вручную аутентифицировать пользователя, сравнивая обычный текст пароля с хешированным паролем в базе данных, используйте удобную функцию check_password(). Она принимает два обязательных аргумента: текст пароля для проверки и полное значение поля password пользователя в базе данных для проверки. Она возвращает True если они совпадают, False в противном случае. Необязательно, вы можете передать вызываемый setter, который принимает пароль и будет вызван, когда потребуется его сгенерировать. Вы также можете передать preferred для изменения алгоритма хеширования, если вы не хотите использовать алгоритм по умолчанию (первый элемент в настройке PASSWORD_HASHERS). См. Включённые хешеры для имени алгоритма каждого хешера.

Изменено в Django 5.0:

Метод acheck_password() был добавлен.

make_password(password, salt=None, hasher='default') [source]

Создаёт хешированный пароль в формате, используемом этим приложением. Она принимает один обязательный аргумент: пароль в виде обычного текста (строка или байты). Необязательно, вы можете указать соль и алгоритм хеширования для использования, если вы не хотите использовать значения по умолчанию (первый элемент в настройке PASSWORD_HASHERS). См. Включённые хешеры для имени алгоритма каждого хешера. Если аргумент password является None, возвращается непригодный пароль (такой, который никогда не будет принят check_password()).

is_password_usable(encoded_password) [source]

Возвращает 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 включает четыре валидатора:

class MinimumLengthValidator(min_length=8) [source]

Проверяет, что длина пароля не менее минимальной. Минимальная длина может быть настраиваема с помощью параметра min_length.

class UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7) [source]

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

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

Максимально допустимое сходство паролей может быть установлено в диапазоне от 0,1 до 1,0 с помощью параметра max_similarity. Это сравнивается с результатом difflib.SequenceMatcher.quick_ratio(). Значение 0,1 отклоняет пароли, если они существенно не отличаются от user_attributes, тогда как значение 1,0 отклоняет только пароли, которые идентичны значению атрибута.

class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH) [source]

Проверяет, что пароль не является общим паролем. Это преобразует пароль в нижний регистр (для выполнения сравнения без учёта регистра) и проверяет его на соответствие списку из 20 000 общих паролей, созданных Royce Williams.

Параметр password_list_path может быть установлен на путь к пользовательскому файлу общих паролей. Этот файл должен содержать один пароль в нижнем регистре на каждой строке и может быть текстовым или сжатым в формате gzip.

class NumericPasswordValidator [source]

Проверяет, что пароль не состоит полностью из цифр.

Интегрирование валидации

В django.contrib.auth.password_validation есть несколько функций, которые можно вызывать из собственных форм или другого кода для интеграции валидации паролей. Это может быть полезно, если вы используете пользовательские формы для установки паролей или если у вас есть API-вызовы, которые позволяют устанавливать пароли, например.

validate_password(password, user=None, password_validators=None) [source]

Валидирует пароль. Если все валидаторы находят пароль действительным, возвращает None. Если один или несколько валидаторов отклоняют пароль, возникает исключение ValidationError со всеми сообщениями об ошибках от валидаторов.

Объект user является необязательным: если он не предоставлен, некоторые валидаторы могут не быть в состоянии выполнить валидацию и примут любой пароль.

password_changed(password, user=None, password_validators=None) [source]

Сообщает всем валидаторам, что пароль был изменён. Это может использоваться валидаторами, например, предотвращающими повторное использование паролей. Это должно быть вызвано после успешного изменения пароля.

Для подклассов AbstractBaseUser, поле пароля будет помечено как «изменённое» при вызове set_password(), что инициирует вызов password_changed() после сохранения пользователя.

password_validators_help_texts(password_validators=None) [source]

Возвращает список текстов справки всех валидаторов. Они объясняют требования к паролю пользователю.

password_validators_help_text_html(password_validators=None)

Возвращает HTML-строку со всеми текстами справки в <ul>. Это полезно при добавлении валидации паролей в формы, поскольку вы можете передать вывод непосредственно в параметр help_text поля формы.

get_password_validators(validator_config) [source]

Возвращает набор объектов валидаторов на основе параметра 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 в 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), который будет вызываться после успешной смены пароля. Это можно использовать, например, для предотвращения повторного использования паролей. Однако, если вы решите хранить предыдущие пароли пользователя, никогда не делайте этого в открытом тексте.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/topics/auth/passwords/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API