Spec-Zone.ru › Django 4.2

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

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

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

  1. Установите библиотеку argon2-cffi. Это можно сделать, выполнив команду python -m pip install django[argon2], что эквивалентно python -m pip install argon2-cffi, а также любые требования к версии из setup.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.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, а также любые требования к версии из setup.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.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 для объёма памяти (в KiB), который вы можете использовать.
  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.

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

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

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

check_password(password, encoded, setter=None, preferred='default')

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

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 отклоняет только пароли, идентичные значению атрибута.

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

Параметр max_similarity был ограничен минимальным значением 0,1.

class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)

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

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

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

Список из 20 000 распространённых паролей был обновлён до последней версии.

class NumericPasswordValidator

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

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

В 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/4.2/topics/auth/passwords/

Spec-Zone.ru

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