• 3.1
  • 3.2
  • 6.1
  • Версия документации: 5.0

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

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

См.также

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

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

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

Атрибут password объекта User представляет собой строку в следующем формате:

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

Данная строка показывает компоненты, которые используются для хранения пользовательского пароля и разделены знаком доллара, а именно: хэширующий алгоритм, количество итераций алгоритма (work factor), случайная соль и полученный хэш пароля. Алгоритмом может быть любой из ряда однонаправленных хэширующих алгоритмов, которые использует 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, bcrypt, SHA1 и так далее. Следующие несколько разделов описывают ряд общих способов, которые могут быть использованы опытными пользователями для изменения данного параметра конфигурации.

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

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

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

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

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

  1. Установите пакет argon2-cffi. Это можно сделать, запустив python -m pip install django[argon2], что эквивалентно python -m pip install argon2-cffi (вместе с любыми требованиями к версии из pyproject.toml Django).

  2. Измените PASSWORD_HASHERS так, чтобы BCryptSHA256PasswordHasher был указан первым. То есть, в файле конфигурации надо сделать так:

    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 в качестве алгоритма по умолчанию, выполните следующие действия:

  1. Установите пакет bcrypt. Это можно сделать, запустив python -m pip install django[bcrypt], что эквивалентно python -m pip install bcrypt (вместе с любыми требованиями к версии из pyproject.toml Django).

  2. Измените PASSWORD_HASHERS так, чтобы BCryptSHA256PasswordHasher был указан первым. То есть, в файле конфигурации надо сделать так:

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

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

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

Увеличение сложности хэша

PBKDF2 и bcrypt

Алгоритмы PBKDF2 и bcrypt используют несколько итераций или раундов хеширования. Это намеренно замедляет атаку злоумышленников, усложняя атаки на хешированные пароли. Однако по мере увеличения вычислительной мощности количество итераций необходимо увеличивать. Мы выбрали разумное значение по умолчанию (и будем увеличивать его с каждым выпуском Django), но вы можете увеличить или уменьшить его, в зависимости от ваших потребностей в безопасности и доступной вычислительной мощности. Для этого вы создадите подкласс соответствующего алгоритма и переопределите параметр iterations (используйте параметр rounds при создании подкласса хэшера bcrypt). Например, чтобы увеличить количество итераций, используемых алгоритмом PBKDF2 по умолчанию:

  1. Создайте подкласс django.contrib.auth.hashers.PBKDF2PasswordHasher:

    from django.contrib.auth.hashers import PBKDF2PasswordHasher
    
    
    class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
        """
        A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
        """
    
        iterations = PBKDF2PasswordHasher.iterations * 100
    

    Сохраните это в ваш проект. Например, вы можете разместить это в файле подобном myproject/hashers.py.

  2. Добавьте новый алгоритм хэширования в начало списка конфигурационного параметра PASSWORD_HASHERS:

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

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

Примечание

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

Аргон2

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

  1. time_cost контролирует количество итераций в хеше.

  2. memory_cost контролирует размер памяти, которая должна использоваться во время вычисления хеша.

  3. параллелизм контролирует, на скольких процессорах может быть распараллелено вычисление хеша.

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

  1. Выберите «параллелизм», чтобы указать количество потоков, которые вы можете выделить для вычисления хэша.

  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 имеет следующие атрибуты, которые можно настроить:

  1. work_factor контролирует количество итераций в хеше.

  2. block_size

  3. параллелизм контролирует, сколько потоков будет выполняться параллельно.

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

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

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

  • аргон2

  • bcrypt_sha256

  • bcrypt

  • скрипт

  • md5

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

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

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

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

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

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

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

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

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

Changed in Django 5.0:

Добавлен метод acheck_password().

make_password(password, salt=None, hasher='default')

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

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

Back to Top