Spec-Zone.ru › Django 4.0

Управление паролями в 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.contrib.auth.hashers.ScryptPasswordHasher',
]

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

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

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

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

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

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

  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

Новое в Django 4.0.

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

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

Новое в Django 3.2.

Большинство хэшей паролей включают соль вместе с хэшем пароля для защиты от атак с помощью радужных таблиц. Сама соль — это случайное значение, которое увеличивает размер и, следовательно, стоимость радужной таблицы, и в настоящее время установлено на 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:
  2. 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.

  3. Добавьте свой новый хэшер в качестве первого элемента в PASSWORD_HASHERS:
  4. 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

Новое в Django 4.0.

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

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

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

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)

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

accounts/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.ScryptPasswordHasher',
    '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
  • scrypt
  • sha1
  • md5
  • unsalted_sha1
  • unsalted_md5
  • crypt

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

Если вы пишете собственный хэшировщик паролей, содержащий множитель работы, такой как количество итераций, вы должны реализовать метод 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)

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

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 с помощью параметра max_similarity. Значение 0 отвергает все пароли, а значение 1 отвергает только пароли, идентичные значению атрибута.

class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)

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

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

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.0/topics/auth/passwords/

Spec-Zone.ru

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