Spec-Zone.ru › Django 4.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 не является по умолчанию для Django, поскольку для него требуется библиотека сторонних разработчиков. Однако панель конкурса по хэшированию паролей рекомендует немедленное использование Argon2 вместо других поддерживаемых Django алгоритмов.

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

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

Новое в 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+.

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

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

Новое в 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',
]

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

  • pbkdf2_sha256
  • pbkdf2_sha1
  • argon2
  • bcrypt_sha256
  • bcrypt
  • scrypt
  • sha1
  • md5
  • unsalted_sha1
  • unsalted_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)

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

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

Spec-Zone.ru

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