Spec-Zone.ru › Django 6.0

Управление паролями в 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 года, организованного сообществом открытого конкурса по выбору алгоритма хеширования следующего поколения. Он разработан таким образом, чтобы вычислять его на специализированном оборудовании было не проще, чем на обычном процессоре. Вариант Argon2id используется по умолчанию в алгоритме хеширования паролей Argon2.

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 (при создании подкласса хешера bcrypt используйте параметр rounds). Например, чтобы увеличить количество итераций, используемых алгоритмом 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.

Примечание

rounds bcrypt — это логарифмический рабочий фактор: например, 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

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

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

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

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

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

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

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

В этом примере мы преобразуем набор хешей MD5, чтобы использовать PBKDF2(MD5(password)), и добавим соответствующий алгоритм хеширования паролей для проверки правильности пароля, введенного пользователем при входе. Предполагается, что мы используем встроенную модель 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, и рабочим фактором алгоритма по умолчанию. Это предотвращает атаку по времени выполнения, позволяющую перечислять пользователей, из-за разницы между запросом на вход пользователя с паролем, закодированным с меньшим числом итераций, и запросом для несуществующего пользователя (для которого запускается алгоритм хеширования с числом итераций по умолчанию).

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

Если у вашего алгоритма хеширования нет рабочего фактора, реализуйте этот метод как пустую операцию (pass).

Ручное управление паролем пользователя

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

check_password(password, encoded, setter=None, preferred='default') [источник]
acheck_password(password, encoded, asetter=None, preferred='default')

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

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

make_password(password, salt=None, hasher='default') [источник]

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

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

class MinimumLengthValidator(min_length=8) [исходный код]

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

get_error_message() [исходный код]
Добавлено в Django 5.2.

Точка расширения для настройки сообщения об ошибке ValidationError. По умолчанию используется "This password is too short. It must contain at least <min_length> characters.".

get_help_text() [исходный код]

Точка расширения для настройки текста справки валидатора. По умолчанию используется "Your password must contain at least <min_length> characters.".

class UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7) [исходный код]

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

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

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

get_error_message() [исходный код]
Добавлено в Django 5.2.

Точка расширения для настройки сообщения об ошибке ValidationError. По умолчанию используется "The password is too similar to the <user_attribute>.".

get_help_text() [исходный код]

Точка расширения для настройки текста справки валидатора. По умолчанию используется "Your password can’t be too similar to your other personal information.".

class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH) [исходный код]

Проверяет, что пароль не является распространённым. Для сравнения без учёта регистра пароль преобразуется в нижний регистр, а затем сверяется со списком из 20 000 распространённых паролей, созданным Ройсом Уильямсом.

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

get_error_message() [исходный код]
Добавлено в Django 5.2.

Точка расширения для настройки сообщения об ошибке ValidationError. По умолчанию используется "This password is too common.".

get_help_text() [исходный код]

Точка расширения для настройки текста справки валидатора. По умолчанию используется "Your password can’t be a commonly used password.".

class NumericPasswordValidator [исходный код]

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

get_error_message() [исходный код]
Добавлено в Django 5.2.

Точка расширения для настройки сообщения об ошибке ValidationError. По умолчанию используется "This password is entirely numeric.".

get_help_text() [исходный код]

Точка расширения для настройки текста справки валидатора. По умолчанию используется "Your password can’t be entirely numeric.".

Интеграция проверки

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

validate_password(password, user=None, password_validators=None) [исходный код]

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

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

password_changed(password, user=None, password_validators=None) [исходный код]

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

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

password_validators_help_texts(password_validators=None) [исходный код]

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

password_validators_help_text_html(password_validators=None)

Возвращает 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 в параметре 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/6.0/topics/auth/passwords/

Spec-Zone.ru

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