Spec-Zone.ru › Django 4.0

Использование системы аутентификации Django

В этом документе описывается использование системы аутентификации Django в её стандартной конфигурации. Эта конфигурация разработана для удовлетворения наиболее распространённых потребностей проектов, обрабатывая широкий спектр задач, и имеет продуманную реализацию паролей и разрешений. Для проектов, где потребности в аутентификации отличаются от стандартных, Django поддерживает расширенную настройку и расширение системы аутентификации.

Система аутентификации Django обеспечивает как аутентификацию, так и авторизацию, и обычно называется системой аутентификации, так как эти функции несколько взаимосвязаны.

User объекты

User объекты являются основой системы аутентификации. Они обычно представляют людей, взаимодействующих с вашим сайтом, и используются для таких задач, как ограничение доступа, регистрация профилей пользователей, привязка контента к создателям и т. д. В рамках фреймворка аутентификации Django существует только один класс пользователей, т. е. 'superusers' или администраторские 'staff' пользователи — это всего лишь пользовательские объекты со специальными атрибутами, а не разные классы пользовательских объектов.

Основные атрибуты стандартного пользователя:

  • username
  • password
  • email
  • first_name
  • last_name

См. full API documentation для полного справочника, следующая документация более ориентирована на задачи.

Создание пользователей

Наиболее прямой способ создания пользователей — использование встроенной функции create_user():

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')

# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = 'Lennon'
>>> user.save()

Если у вас установлен Django admin, вы также можете создавать пользователей интерактивно.

Создание суперпользователей

Создайте суперпользователей с помощью команды createsuperuser:

$ python manage.py createsuperuser --username=joe --email=joe@example.com

Вам будет предложено ввести пароль. После ввода пароль будет сразу же сохранён. Если вы опустите опции --username или --email, вам будет предложено ввести эти значения.

Изменение паролей

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

Для изменения пароля пользователя у вас есть несколько вариантов:

manage.py changepassword *username* предлагает способ изменения пароля пользователя из командной строки. Вам будет предложено изменить пароль указанного пользователя, который вы должны ввести дважды. Если оба значения совпадают, новый пароль будет изменён сразу же. Если вы не укажете пользователя, команда попытается изменить пароль пользователя с именем, соответствующим текущему системному пользователю.

Вы также можете изменить пароль программно, используя set_password():

>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()

Если у вас установлен Django admin, вы также можете изменить пароли пользователей на страницах администратора системы аутентификации.

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

Изменение пароля пользователя приведёт к выходу из всех их сессий. Подробности см. в разделе Недействительность сессии при смене пароля.

Аутентификация пользователей

authenticate(request=None, **credentials)

Используйте authenticate() для проверки набора учетных данных. Он принимает учетные данные в качестве ключевых аргументов, username и password в стандартном случае, проверяет их по каждому аутентификационному бэкенду и возвращает объект User, если учетные данные действительны для бэкенда. Если учетные данные не действительны ни для одного бэкенда или если бэкенд генерирует PermissionDenied, он возвращает None. Например:

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # A backend authenticated the credentials
else:
    # No backend authenticated the credentials

request — это необязательный HttpRequest, который передаётся в метод authenticate() аутентификационных бэкендов.

Примечание

Это низкоуровневый способ аутентификации набора учетных данных; например, он используется RemoteUserMiddleware. Если вы не пишете собственную систему аутентификации, вы, скорее всего, не будете использовать её. Вместо этого, если вы ищете способ входа пользователя, используйте LoginView.

Разрешения и авторизация

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

Она используется в админ-панели Django, но вы можете использовать её и в своём коде.

Админ-панель Django использует разрешения следующим образом:

  • Доступ к просмотру объектов ограничен для пользователей с разрешением «просмотр» или «изменение» для этого типа объекта.
  • Доступ к форме «добавления» и добавлению объекта ограничен для пользователей с разрешением «добавление» для этого типа объекта.
  • Доступ к просмотру списка изменений, просмотру формы «изменение» и изменению объекта ограничен для пользователей с разрешением «изменение» для этого типа объекта.
  • Доступ к удалению объекта ограничен для пользователей с разрешением «удаление» для этого типа объекта.

Разрешения могут быть установлены не только для типа объекта, но и для конкретного экземпляра объекта. Используя методы has_view_permission(), has_add_permission(), has_change_permission() и has_delete_permission(), предоставляемые классом ModelAdmin, можно настраивать разрешения для различных экземпляров объектов одного типа.

User объекты имеют два поля many-to-many: groups и user_permissions. User объекты могут получать доступ к связанным объектам так же, как и любой другой Django-модель:

myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

Стандартные разрешения

Когда django.contrib.auth указан в настройке INSTALLED_APPS, он гарантирует, что для каждой модели Django, определённой в одном из ваших установленных приложений, будут созданы четыре стандартных разрешения — добавление, изменение, удаление и просмотр.

Эти разрешения будут созданы при выполнении manage.py migrate; в первый раз при выполнении migrate после добавления django.contrib.auth в INSTALLED_APPS, будут созданы стандартные разрешения для всех ранее установленных моделей, а также для любых новых моделей, установленных в это время. После этого он будет создавать стандартные разрешения для новых моделей каждый раз при выполнении manage.py migrate (функция, создающая разрешения, связана со сигналом post_migrate).

Предполагая, что у вас есть приложение с app_label foo и моделью с именем Bar, для проверки основных разрешений следует использовать:

  • добавление: user.has_perm('foo.add_bar')
  • изменение: user.has_perm('foo.change_bar')
  • удаление: user.has_perm('foo.delete_bar')
  • просмотр: user.has_perm('foo.view_bar')

Модель Permission редко используется напрямую.

Группы

django.contrib.auth.models.Group — это универсальный способ категоризации пользователей, позволяющий применять разрешения или какие-либо другие метки к этим пользователям. Пользователь может принадлежать к любому количеству групп.

Пользователь в группе автоматически обладает разрешениями, предоставленными этой группе. Например, если группа Site editors имеет разрешение can_edit_home_page, любой пользователь в этой группе будет обладать этим разрешением.

Помимо разрешений, группы являются удобным способом категоризации пользователей, чтобы присвоить им метки или расширенные функции. Например, вы можете создать группу 'Special users', и вы можете написать код, который, скажем, предоставит им доступ к закрытой части вашего сайта или отправит им закрытые электронные письма.

Программирование создания разрешений

В то время как настраиваемые разрешения могут быть определены в классе Meta модели, вы также можете создавать разрешения напрямую. Например, вы можете создать разрешение can_publish для модели BlogPost в myapp:

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
    codename='can_publish',
    name='Can Publish Posts',
    content_type=content_type,
)

Затем разрешение можно назначить пользователю User через его атрибут user_permissions или группе Group через её атрибут permissions.

Моделям-прокси требуется собственный тип содержимого

Если вы хотите создать разрешения для модели-прокси, передайте for_concrete_model=False в ContentTypeManager.get_for_model(), чтобы получить соответствующий тип содержимого ContentType:

content_type = ContentType.objects.get_for_model(BlogPostProxy, for_concrete_model=False)

Кэширование разрешений

Backend ModelBackend кэширует разрешения на объекте пользователя после первого запроса для проверки разрешений. Обычно это нормально для цикла запроса-ответа, так как разрешения обычно не проверяются сразу после добавления (например, в админке). Если вы добавляете разрешения и проверяете их сразу после этого, например, в тесте или представлении, самый простой способ — повторно получить пользователя из базы данных. Например:

from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404

from myapp.models import BlogPost

def user_gains_perms(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    # any permission check will cache the current set of permissions
    user.has_perm('myapp.change_blogpost')

    content_type = ContentType.objects.get_for_model(BlogPost)
    permission = Permission.objects.get(
        codename='change_blogpost',
        content_type=content_type,
    )
    user.user_permissions.add(permission)

    # Checking the cached permission set
    user.has_perm('myapp.change_blogpost')  # False

    # Request new instance of User
    # Be aware that user.refresh_from_db() won't clear the cache.
    user = get_object_or_404(User, pk=user_id)

    # Permission cache is repopulated from the database
    user.has_perm('myapp.change_blogpost')  # True

    ...

Модели-прокси

Модели-прокси работают точно так же, как и конкретные модели. Разрешения создаются с использованием собственного типа содержимого модели-прокси. Модели-прокси не наследуют разрешений от конкретной модели, которую они наследуют:

class Person(models.Model):
    class Meta:
        permissions = [('can_eat_pizzas', 'Can eat pizzas')]

class Student(Person):
    class Meta:
        proxy = True
        permissions = [('can_deliver_pizzas', 'Can deliver pizzas')]

>>> # Fetch the content type for the proxy model.
>>> content_type = ContentType.objects.get_for_model(Student, for_concrete_model=False)
>>> student_permissions = Permission.objects.filter(content_type=content_type)
>>> [p.codename for p in student_permissions]
['add_student', 'change_student', 'delete_student', 'view_student',
'can_deliver_pizzas']
>>> for permission in student_permissions:
...     user.user_permissions.add(permission)
>>> user.has_perm('app.add_person')
False
>>> user.has_perm('app.can_eat_pizzas')
False
>>> user.has_perms(('app.add_student', 'app.can_deliver_pizzas'))
True

Аутентификация в веб-запросах

Django использует сессии и middleware для подключения системы аутентификации к request objects.

Они предоставляют атрибут request.user в каждом запросе, который представляет текущего пользователя. Если текущий пользователь не вошел в систему, этот атрибут будет установлен в экземпляр AnonymousUser, в противном случае — в экземпляр User.

Вы можете отличить их с помощью is_authenticated, как показано ниже:

if request.user.is_authenticated:
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

Как войти в систему

Если у вас есть аутентифицированный пользователь, которого вы хотите прикрепить к текущей сессии, это делается с помощью функции login().

login(request, user, backend=None)

Для входа в систему пользователя из представления используйте login(). Она принимает объект HttpRequest и объект User. login() сохраняет идентификатор пользователя в сессии, используя фреймворк сессий Django.

Обратите внимание, что все данные, заданные во время анонимной сессии, сохраняются в сессии после входа в систему пользователя.

Этот пример показывает, как вы можете использовать и authenticate(), и login():

from django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        # Redirect to a success page.
        ...
    else:
        # Return an 'invalid login' error message.
        ...

Выбор бэкенда аутентификации

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

  1. Используйте значение необязательного аргумента backend (если он указан).
  2. Используйте значение атрибута user.backend (если он существует). Это позволяет сопоставить authenticate() и login(): authenticate() устанавливает атрибут user.backend на объекте пользователя, который он возвращает.
  3. Используйте значение backend в AUTHENTICATION_BACKENDS (если существует только одно).
  4. В противном случае вызовите исключение.

В случаях 1 и 2 значение аргумента backend или атрибута user.backend должно быть строкой импорта с точками (как в AUTHENTICATION_BACKENDS), а не самим классом бэкенда.

Как выйти из системы

logout(request)

Чтобы выйти из системы пользователя, вошедшего в систему с помощью django.contrib.auth.login(), используйте django.contrib.auth.logout() в своем представлении. Она принимает объект HttpRequest и не имеет значения возврата. Пример:

from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    # Redirect to a success page.

Обратите внимание, что logout() не вызывает никаких ошибок, если пользователь не был авторизован.

При вызове logout() данные сессии для текущего запроса полностью очищаются. Все существующие данные удаляются. Это предотвращает использование одним и тем же веб-браузером другим человеком для входа в систему и доступа к данным сессии предыдущего пользователя. Если вы хотите поместить что-либо в сессию, которое будет доступно пользователю сразу после выхода из системы, сделайте это после вызова django.contrib.auth.logout().

Ограничение доступа для авторизованных пользователей

Прямой метод

Примитивный способ ограничения доступа к страницам — проверка request.user.is_authenticated и перенаправление на страницу входа:

from django.conf import settings
from django.shortcuts import redirect

def my_view(request):
    if not request.user.is_authenticated:
        return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    # ...

…или отображение сообщения об ошибке:

from django.shortcuts import render

def my_view(request):
    if not request.user.is_authenticated:
        return render(request, 'myapp/login_error.html')
    # ...

Декоратор login_required

login_required(redirect_field_name='next', login_url=None)

В качестве обходного пути можно использовать удобный декоратор login_required():

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ...

login_required() выполняет следующие действия:

  • Если пользователь не авторизован, перенаправляет его на settings.LOGIN_URL, передавая текущий абсолютный путь в строке запроса. Пример: /accounts/login/?next=/polls/3/.
  • Если пользователь авторизован, выполняет представление обычно. Код представления может предполагать, что пользователь авторизован.

По умолчанию путь, на который пользователь должен быть перенаправлен после успешной авторизации, хранится в параметре строки запроса под названием "next". Если вы хотите использовать другое имя для этого параметра, декоратор login_required() принимает необязательный параметр redirect_field_name:

from django.contrib.auth.decorators import login_required

@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
    ...

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

login_required() также принимает необязательный параметр login_url. Пример:

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
    ...

Обратите внимание, что если вы не укажете параметр login_url, вам необходимо убедиться, что settings.LOGIN_URL и ваше представление входа корректно связаны. Например, используя значения по умолчанию, добавьте следующие строки в свой файл URLconf:

from django.contrib.auth import views as auth_views

path('accounts/login/', auth_views.LoginView.as_view()),

settings.LOGIN_URL также принимает имена функций представления и имена шаблонов URL. Это позволяет вам свободно переназначать ваше представление входа в файле URLconf без необходимости обновления настроек.

Примечание

Декоратор login_required НЕ проверяет флаг is_active пользователя, но по умолчанию AUTHENTICATION_BACKENDS отклоняет неактивных пользователей.

См. также

Если вы пишете пользовательские представления для администрирования Django (или вам нужна та же проверка авторизации, что и в встроенных представлениях), вы можете найти декоратор django.contrib.admin.views.decorators.staff_member_required() полезной альтернативой декоратору login_required().

Миксин LoginRequired

При работе с представлениями на основе классов, можно добиться такого же поведения, как и с login_required, используя миксин LoginRequiredMixin. Этот миксин должен располагаться левее всего в списке наследования.

class LoginRequiredMixin

Если представление использует этот миксин, все запросы от неавторизованных пользователей будут перенаправлены на страницу входа или отобразить ошибку HTTP 403 Forbidden, в зависимости от параметра raise_exception.

Вы можете настроить любые параметры AccessMixin для настройки обработки неавторизованных пользователей:

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

Примечание

Как и декоратор login_required, этот миксин НЕ проверяет флаг is_active пользователя, но по умолчанию AUTHENTICATION_BACKENDS отклоняет неактивных пользователей.

Ограничение доступа для авторизованных пользователей, прошедших проверку

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

Вы можете запустить свою проверку на request.user непосредственно в представлении. Например, это представление проверяет, имеет ли пользователь электронную почту в нужном домене, и если нет, перенаправляет его на страницу входа:

from django.shortcuts import redirect

def my_view(request):
    if not request.user.email.endswith('@example.com'):
        return redirect('/login/?next=%s' % request.path)
    # ...
user_passes_test(test_func, login_url=None, redirect_field_name='next')

В качестве обходного пути можно использовать удобный декоратор user_passes_test, который выполняет перенаправление, когда вызываемый объект возвращает False:

from django.contrib.auth.decorators import user_passes_test

def email_check(user):
    return user.email.endswith('@example.com')

@user_passes_test(email_check)
def my_view(request):
    ...

user_passes_test() принимает обязательный аргумент: вызываемый объект, который принимает объект User и возвращает True, если пользователю разрешено просматривать страницу. Обратите внимание, что user_passes_test() не проверяет автоматически, что User не анонимный.

user_passes_test() принимает два необязательных аргумента:

login_url
Позволяет указать URL, на который будут перенаправлены пользователи, не прошедшие проверку. Это может быть страница входа и по умолчанию равна settings.LOGIN_URL, если вы не укажете другой.
redirect_field_name
Аналогично параметру для login_required(). Установка его в значение None удаляет его из URL, что может потребоваться, если вы перенаправляете пользователей, не прошедших проверку, на страницу, где нет входа и параметра «следующая страница».

Например:

@user_passes_test(email_check, login_url='/login/')
def my_view(request):
    ...
class UserPassesTestMixin

При работе с представлениями на основе классов, вы можете использовать UserPassesTestMixin для этого.

test_func()

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

from django.contrib.auth.mixins import UserPassesTestMixin

class MyView(UserPassesTestMixin, View):

    def test_func(self):
        return self.request.user.email.endswith('@example.com')
get_test_func()

Вы также можете переопределить метод get_test_func() , чтобы миксин использовал функцию с другим именем для проверок (вместо test_func()).

Использование нескольких UserPassesTestMixin

Из-за способа реализации UserPassesTestMixin их нельзя использовать в списке наследования. Следующее НЕ работает:

class TestMixin1(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.email.endswith('@example.com')

class TestMixin2(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.username.startswith('django')

class MyView(TestMixin1, TestMixin2, View):
    ...

Если TestMixin1 вызывало бы super() и учитывало бы этот результат, TestMixin1 больше не работало бы автономно.

Декоратор permission_required

permission_required(perm, login_url=None, raise_exception=False)

Это относительно распространённая задача — проверить, обладает ли пользователь определённым правом. По этой причине Django предоставляет сокращённый вариант для этого случая: декоратор permission_required().

from django.contrib.auth.decorators import permission_required

@permission_required('polls.add_choice')
def my_view(request):
    ...

Так же, как и метод has_perm(), имена разрешений имеют вид "<app label>.<permission codename>" (то есть polls.add_choice для разрешения на модель в приложении polls).

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

Обратите внимание, что permission_required() также принимает необязательный параметр login_url:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.add_choice', login_url='/loginpage/')
def my_view(request):
    ...

Как и в декораторе login_required(), параметр login_url по умолчанию равен settings.LOGIN_URL.

Если параметр raise_exception задан, декоратор будет поднимать исключение PermissionDenied, вызывая отображение страницы 403 (HTTP Forbidden) вместо перенаправления на страницу входа.

Если вы хотите использовать raise_exception и при этом дать пользователям возможность сначала войти в систему, вы можете добавить декоратор login_required():

from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required('polls.add_choice', raise_exception=True)
def my_view(request):
    ...

Это также предотвращает цикл перенаправлений, когда LoginView’s redirect_authenticated_user=True и авторизованный пользователь не обладает всеми необходимыми правами.

Mixin PermissionRequiredMixin

Для применения проверок разрешений к представлениям на основе классов, вы можете использовать PermissionRequiredMixin:

class PermissionRequiredMixin

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

from django.contrib.auth.mixins import PermissionRequiredMixin

class MyView(PermissionRequiredMixin, View):
    permission_required = 'polls.add_choice'
    # Or multiple of permissions:
    permission_required = ('polls.view_choice', 'polls.change_choice')

Вы можете задать любые параметры миксина AccessMixin для настройки обработки неавторизованных пользователей.

Вы также можете переопределить следующие методы:

get_permission_required()

Возвращает итерируемый объект имён разрешений, используемых миксином. По умолчанию возвращает атрибут permission_required , преобразованный в кортеж, если необходимо.

has_permission()

Возвращает булево значение, обозначающее, обладает ли текущий пользователь разрешением на выполнение декорированного представления. По умолчанию возвращает результат вызова has_perms() со списком разрешений, возвращаемым методом get_permission_required().

Перенаправление неавторизованных запросов в представлениях на основе классов

Для упрощения обработки ограничений доступа в представлениях на основе классов, можно использовать AccessMixin для настройки поведения представления при отказе в доступе. Авторизованным пользователям доступ запрещается с ответом HTTP 403 Forbidden. Анонимным пользователям предлагается перенаправление на страницу входа или отображение ответа HTTP 403 Forbidden, в зависимости от атрибута raise_exception.

class AccessMixin
login_url

Значение по умолчанию для get_login_url(). По умолчанию равно None, в этом случае get_login_url() ссылается на settings.LOGIN_URL.

permission_denied_message

Значение по умолчанию для get_permission_denied_message(). По умолчанию пустая строка.

redirect_field_name

Значение по умолчанию для get_redirect_field_name(). По умолчанию "next".

raise_exception

Если этот атрибут установлен в True, исключение PermissionDenied поднимается при невыполнении условий. Когда установлено значение False (по умолчанию), анонимные пользователи перенаправляются на страницу входа.

get_login_url()

Возвращает URL, на который будут перенаправлены пользователи, не прошедшие проверку. Возвращает значение login_url, если оно задано, или settings.LOGIN_URL в противном случае.

get_permission_denied_message()

Когда raise_exception равно True, этот метод можно использовать для управления сообщением об ошибке, передаваемым обработчику ошибок для отображения пользователю. По умолчанию возвращает атрибут permission_denied_message.

get_redirect_field_name()

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

handle_no_permission()

В зависимости от значения raise_exception, метод либо поднимает исключение PermissionDenied, либо перенаправляет пользователя на login_url, необязательно включая redirect_field_name , если оно задано.

Отключение сессий при изменении пароля

Если ваша модель пользователя AUTH_USER_MODEL унаследована от AbstractBaseUser или реализует свой метод get_session_auth_hash(), авторизованные сессии будут включать хеш, возвращённый этой функцией. В случае с AbstractBaseUser, это HMAC от поля пароля. Django проверяет, что хеш в сессии для каждого запроса соответствует тому, который вычисляется во время запроса. Это позволяет пользователю выйти из всех своих сессий, изменив пароль.

Предустановленные в Django представления для изменения пароля, PasswordChangeView и представление user_change_password в админке django.contrib.auth, обновляют сеанс с новым хэшем пароля, чтобы пользователь, меняющий свой пароль, не выходил из системы. Если у вас есть пользовательское представление для изменения пароля и вы хотите получить подобное поведение, используйте функцию update_session_auth_hash().

update_session_auth_hash(request, user)

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

Пример использования:

from django.contrib.auth import update_session_auth_hash

def password_change(request):
    if request.method == 'POST':
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(request, form.user)
    else:
        ...

Примечание

Поскольку get_session_auth_hash() основан на SECRET_KEY, обновление сайта с использованием нового секрета сделает все существующие сессии недействительными.

Представления аутентификации

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

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

Использование представлений

Существует несколько способов реализации этих представлений в вашем проекте. Самый простой способ — включить предоставленный URLconf в django.contrib.auth.urls в вашем собственном URLconf, например:

urlpatterns = [
    path('accounts/', include('django.contrib.auth.urls')),
]

Это включит следующие URL-образцы:

accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']

Представления предоставляют имя URL для более удобной ссылки. Подробнее об использовании именованных URL-образцов см. в документации по URL.

Если вы хотите иметь больший контроль над своими URL, вы можете обратиться к конкретному представлению в своём URLconf:

from django.contrib.auth import views as auth_views

urlpatterns = [
    path('change-password/', auth_views.PasswordChangeView.as_view()),
]

Представления имеют необязательные аргументы, которые вы можете использовать для изменения поведения представления. Например, если вы хотите изменить имя шаблона, которое использует представление, вы можете передать аргумент template_name. Способ сделать это — передать ключевые аргументы в URLconf, которые будут переданы представлению. Например:

urlpatterns = [
    path(
        'change-password/',
        auth_views.PasswordChangeView.as_view(template_name='change-password.html'),
    ),
]

Все представления основаны на классах, что позволяет легко настраивать их, создавая подклассы.

Все представления аутентификации

Это список всех представлений, которые django.contrib.auth предоставляет. Подробности реализации см. в Разделе об использовании представлений.

class LoginView

Имя URL: login

Подробную информацию об использовании именованных шаблонов URL см. в документации по URL.

Методы и атрибуты

template_name

Имя шаблона для отображения страницы входа в систему. По умолчанию registration/login.html.

next_page
Новое в Django 4.0.

URL для перенаправления после входа в систему. По умолчанию LOGIN_REDIRECT_URL.

redirect_field_name

Имя поля GET, содержащего URL для перенаправления после входа в систему. По умолчанию next. Переопределяет URL get_default_redirect_url(), если передан параметр GET.

authentication_form

Вызываемый объект (обычно класс формы) для аутентификации. По умолчанию AuthenticationForm.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

redirect_authenticated_user

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

Предупреждение

Если вы включите redirect_authenticated_user, другие веб-сайты смогут определить, авторизованы ли их посетители на вашем сайте, запросив URL-адреса перенаправления к файлам изображений на вашем сайте. Чтобы избежать утечки информации о «отпечатках социальных сетей», размещайте все изображения и favicon на отдельном домене.

Включение redirect_authenticated_user также может привести к циклу перенаправлений при использовании декоратора permission_required(), если не используется параметр raise_exception.

success_url_allowed_hosts

Множество хостов, помимо request.get_host(), которые безопасны для перенаправления после входа в систему. По умолчанию пустое множество set.

get_default_redirect_url()
Новое в Django 4.0.

Возвращает URL для перенаправления после входа в систему. Реализация по умолчанию определяет и возвращает next_page, если он задан, или LOGIN_REDIRECT_URL в противном случае.

Вот что делает LoginView:

  • Если вызвано через GET, отображается форма входа, которая POST-запросом отправляется на тот же URL. Подробнее об этом чуть позже.
  • Если вызвано через POST с предоставленными пользователем учетными данными, происходит попытка входа в систему. Если вход успешен, представление перенаправляет на URL, указанный в next. Если next не указано, происходит перенаправление на settings.LOGIN_REDIRECT_URL (который по умолчанию /accounts/profile/). Если вход не успешен, форма входа отображается повторно.

Вы должны предоставить html для шаблона входа в систему, который по умолчанию называется registration/login.html. Этот шаблон получает четыре переменные контекста шаблона:

  • form: Объект Form, представляющий AuthenticationForm.
  • next: URL для перенаправления после успешного входа. Он может также содержать строку запроса.
  • site: Текущий Site в соответствии с настройкой SITE_ID. Если у вас не установлен фреймворк сайтов, это будет экземпляр RequestSite, который определяет имя сайта и домен из текущего HttpRequest.
  • site_name: Псевдоним для site.name. Если у вас не установлен фреймворк сайтов, это будет значение request.META['SERVER_NAME']. Дополнительную информацию о сайтах см. в фреймворке «сайты».

Если вы предпочитаете не вызывать шаблон registration/login.html, вы можете передать параметр template_name через дополнительные аргументы к методу as_view в вашем URLconf. Например, эта строка URLconf будет использовать myapp/login.html вместо этого:

path('accounts/login/', auth_views.LoginView.as_view(template_name='myapp/login.html')),

Вы также можете указать имя поля GET, содержащего URL для перенаправления после входа в систему, используя redirect_field_name. По умолчанию поле называется next.

Вот пример шаблона registration/login.html, который вы можете использовать в качестве отправной точки. Предполагается, что у вас есть шаблон base.html, который определяет блок content:

{% extends "base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}

{% if next %}
    {% if user.is_authenticated %}
    <p>Your account doesn't have access to this page. To proceed,
    please login with an account that has access.</p>
    {% else %}
    <p>Please login to see this page.</p>
    {% endif %}
{% endif %}

<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
    <td>{{ form.username.label_tag }}</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>{{ form.password.label_tag }}</td>
    <td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="login">
<input type="hidden" name="next" value="{{ next }}">
</form>

{# Assumes you set up the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>

{% endblock %}

Если вы настраиваете аутентификацию (см. Настройка аутентификации), вы можете использовать пользовательскую форму аутентификации, установив атрибут authentication_form. Эта форма должна принимать ключевой аргумент request в своем методе __init__() и обеспечивать метод get_user(), который возвращает объект аутентифицированного пользователя (этот метод вызывается только после успешной проверки формы).

class LogoutView

Выход пользователя.

Имя URL: logout

Атрибуты:

next_page

URL для перенаправления после выхода. По умолчанию LOGOUT_REDIRECT_URL.

template_name

Полное имя шаблона для отображения после выхода пользователя. По умолчанию registration/logged_out.html.

redirect_field_name

Имя поля GET содержащего URL для перенаправления после выхода. По умолчанию 'next'. Переопределяет URL next_page, если передан параметр GET.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

success_url_allowed_hosts

set хостов, помимо request.get_host(), которые безопасны для перенаправления после выхода. По умолчанию пустой set.

Контекст шаблона:

  • title: Строка “Выход”, локализованная.
  • site: Текущий Site в соответствии с настройкой SITE_ID. Если модуль сайтов не установлен, это будет экземпляр RequestSite, который получает имя сайта и домен из текущего HttpRequest.
  • site_name: Псевдоним для site.name. Если модуль сайтов не установлен, это будет значение request.META['SERVER_NAME']. Более подробная информация о сайтах в Модуле “сайты”.
logout_then_login(request, login_url=None)

Выход пользователя, затем перенаправление на страницу входа.

Имя URL: Не предоставлено

Дополнительные аргументы:

  • login_url: URL страницы входа для перенаправления. По умолчанию settings.LOGIN_URL, если не указано.
class PasswordChangeView

Имя URL: password_change

Позволяет пользователю изменить пароль.

Атрибуты:

success_url

URL для перенаправления после успешной смены пароля. По умолчанию 'password_change_done'.

form_class

Пользовательская форма «смены пароля», которая должна принимать user аргумент. Форма отвечает за фактическую смену пароля пользователя. По умолчанию PasswordChangeForm.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

Контекст шаблона:

  • form: Форма смены пароля (см. form_class выше).
class PasswordChangeDoneView

Имя URL: password_change_done

Страница, отображаемая после смены пароля пользователем.

Атрибуты:

template_name

Полное имя используемого шаблона. По умолчанию registration/password_change_done.html.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

END_OF_DOCUMENT_MARKER
class PasswordResetView

Имя URL: password_reset

Позволяет пользователю сбросить пароль, сгенерировав одноразовую ссылку для сброса пароля и отправив её на зарегистрированный адрес электронной почты.

Если указанный адрес электронной почты отсутствует в системе, эта страница не отправит письмо, но пользователь также не получит сообщение об ошибке. Это предотвращает утечку информации потенциальным злоумышленникам. Если вы хотите вывести сообщение об ошибке в этом случае, вы можете создать подкласс PasswordResetForm и использовать атрибут form_class.

Примечание

Обратите внимание, что отправка электронной почты занимает дополнительное время, поэтому вы можете быть уязвимы к атакам на перебор адресов электронной почты из-за разницы во времени запроса сброса пароля для существующего адреса и запроса сброса пароля для несуществующего адреса. Чтобы уменьшить нагрузку, вы можете использовать сторонний пакет, позволяющий отправлять письма асинхронно, например, django-mailer.

Пользователи с неиспользуемым паролем (см. set_unusable_password()) не могут запросить сброс пароля, чтобы предотвратить злоупотребление при использовании внешнего источника аутентификации, например, LDAP. Обратите внимание, что они не получат никакого сообщения об ошибке, так как это раскрыло бы существование их учетной записи, но письмо также не будет отправлено.

Атрибуты:

template_name

Полное имя шаблона для отображения формы сброса пароля. По умолчанию registration/password_reset_form.html если не указано.

form_class

Форма, которая будет использоваться для получения адреса электронной почты пользователя, для которого необходимо сбросить пароль. По умолчанию PasswordResetForm.

email_template_name

Полное имя шаблона для создания письма со ссылкой для сброса пароля. По умолчанию registration/password_reset_email.html если не указано.

subject_template_name

Полное имя шаблона для использования в теме письма со ссылкой для сброса пароля. По умолчанию registration/password_reset_subject.txt если не указано.

token_generator

Экземпляр класса для проверки одноразовой ссылки. По умолчанию default_token_generator, это экземпляр django.contrib.auth.tokens.PasswordResetTokenGenerator.

success_url

URL для перенаправления после успешного запроса сброса пароля. По умолчанию 'password_reset_done'.

from_email

Действительный адрес электронной почты. По умолчанию Django использует DEFAULT_FROM_EMAIL.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

html_email_template_name

Полное имя шаблона для создания multipart письма с ссылкой для сброса пароля в формате text/html. По умолчанию HTML-письма не отправляются.

extra_email_context

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

Контекст шаблона:

  • form: форма (см. form_class выше) для сброса пароля пользователя.

Контекст шаблона письма:

  • email: псевдоним для user.email
  • user: текущий User, согласно полю формы email. Только активные пользователи могут сбрасывать свои пароли (User.is_active is True).
  • site_name: псевдоним для site.name. Если фреймворк сайта не установлен, это будет значение request.META['SERVER_NAME']. Более подробная информация о сайтах находится в фреймворке “sites”.
  • domain: псевдоним для site.domain. Если фреймворк сайта не установлен, это будет значение request.get_host().
  • protocol: http или https
  • uid: первичный ключ пользователя, закодированный в base 64.
  • token: Токен для проверки валидности ссылки сброса.

Пример registration/password_reset_email.html (шаблон тела письма):

Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

Тот же контекст шаблона используется для шаблона темы. Тема должна быть строкой простого текста из одной строки.

class PasswordResetDoneView

Имя URL: password_reset_done

Страница, отображаемая после того, как пользователю было отправлено письмо со ссылкой для сброса пароля. Эта страница вызывается по умолчанию, если в PasswordResetView не указан явный URL success_url.

Примечание

Если указанный адрес электронной почты отсутствует в системе, пользователь неактивен или имеет неиспользуемый пароль, пользователь всё равно будет перенаправлен на эту страницу, но письмо не будет отправлено.

Атрибуты:

template_name

Полное имя шаблона. По умолчанию registration/password_reset_done.html если не указано.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

class PasswordResetConfirmView

Имя URL: password_reset_confirm

Отображает форму для ввода нового пароля.

Ключевые аргументы из URL:

  • uidb64: Идентификатор пользователя, закодированный в base 64.
  • token: Токен для проверки валидности пароля.

Атрибуты:

template_name

Полное имя шаблона для отображения подтверждения сброса пароля. Значение по умолчанию registration/password_reset_confirm.html.

token_generator

Экземпляр класса для проверки пароля. По умолчанию default_token_generator, это экземпляр django.contrib.auth.tokens.PasswordResetTokenGenerator.

post_reset_login

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

post_reset_login_backend

Путь к аутентификационному бэкенду, используемому для аутентификации пользователя, если post_reset_login равен True. Требуется только если у вас сконфигурировано несколько AUTHENTICATION_BACKENDS. По умолчанию None.

form_class

Форма, которая будет использоваться для установки пароля. По умолчанию SetPasswordForm.

success_url

URL для перенаправления после завершения сброса пароля. По умолчанию 'password_reset_complete'.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

reset_url_token

Параметр токена, отображаемый как часть URL сброса пароля. По умолчанию 'set-password'.

Контекст шаблона:

  • form: форма (см. form_class выше) для установки нового пароля пользователя.
  • validlink: Булево значение, True, если ссылка (комбинация uidb64 и token ) валидна или еще не использована.
END_OF_DOCUMENT_MARKER
class PasswordResetCompleteView

Имя URL: password_reset_complete

Отображает представление, информирующее пользователя о том, что пароль был успешно изменён.

Атрибуты:

template_name

Полное имя шаблона для отображения представления. По умолчанию registration/password_reset_complete.html.

extra_context

Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

Вспомогательные функции

redirect_to_login(next, login_url=None, redirect_field_name='next')

Перенаправляет на страницу входа в систему, а затем обратно на другую страницу после успешного входа.

Обязательные аргументы:

  • next: URL, на который будет перенаправлено после успешного входа.

Необязательные аргументы:

  • login_url: URL страницы входа в систему, на который будет произведено перенаправление. По умолчанию settings.LOGIN_URL, если не указано.
  • redirect_field_name: Имя поля GET, содержащего URL, на который следует перенаправить после выхода из системы. Переопределяет next если указан аргумент GET.

Встроенные формы

Если вы не хотите использовать встроенные представления, но хотите удобство не писать формы для этой функциональности, система аутентификации предоставляет несколько встроенных форм, расположенных в django.contrib.auth.forms:

Примечание

Встроенные формы аутентификации делают определённые предположения о модели пользователя, с которой они работают. Если вы используете пользовательскую модель, может потребоваться определить собственные формы для системы аутентификации. Для получения дополнительной информации см. документацию о использовании встроенных форм аутентификации с пользовательскими моделями.

class AdminPasswordChangeForm

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

Принимает user в качестве первого позиционного аргумента.

class AuthenticationForm

Форма для входа пользователя в систему.

Принимает request в качестве первого позиционного аргумента, который хранится в экземпляре формы для использования подклассами.

confirm_login_allowed(user)

По умолчанию AuthenticationForm отклоняет пользователей, у которых флаг is_active установлен в False. Вы можете изменить это поведение с помощью настраиваемой политики, определяющей, какие пользователи могут войти. Сделайте это с помощью настраиваемой формы, которая наследуется от AuthenticationForm и переопределяет метод confirm_login_allowed(). Этот метод должен вызывать ValidationError, если данный пользователь не может войти.

Например, чтобы разрешить вход всем пользователям независимо от статуса «активный»:

from django.contrib.auth.forms import AuthenticationForm

class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
    def confirm_login_allowed(self, user):
        pass

(В этом случае вам также потребуется использовать бэкэнд аутентификации, который позволяет входить неактивным пользователям, например, AllowAllUsersModelBackend.)

Или для разрешения входа только некоторым активным пользователям:

class PickyAuthenticationForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not user.is_active:
            raise ValidationError(
                _("This account is inactive."),
                code='inactive',
            )
        if user.username.startswith('b'):
            raise ValidationError(
                _("Sorry, accounts starting with 'b' aren't welcome here."),
                code='no_b_users',
            )
class PasswordChangeForm

Форма, позволяющая пользователю изменить свой пароль.

class PasswordResetForm

Форма для генерации и отправки по электронной почте одноразовой ссылки для сброса пароля пользователя.

send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)

Использует аргументы для отправки EmailMultiAlternatives. Может быть переопределён для настройки отправки электронного письма пользователю.

Параметры:
  • subject_template_name – шаблон для темы.
  • email_template_name – шаблон для тела письма.
  • context – контекст, передаваемый subject_template, email_template, и html_email_template (если он не None).
  • from_email – адрес электронной почты отправителя.
  • to_email – адрес электронной почты запросчика.
  • html_email_template_name – шаблон для HTML-тела; по умолчанию None, в этом случае отправляется текстовое письмо.

По умолчанию save() заполняет context теми же переменными, что PasswordResetView передаёт в свой контекст электронной почты.

class SetPasswordForm

Форма, которая позволяет пользователю изменить пароль без ввода старого пароля.

class UserChangeForm

Форма, используемая в админском интерфейсе для изменения информации и разрешений пользователя.

class UserCreationForm

A ModelForm для создания нового пользователя.

У неё есть три поля: username (из модели пользователя), password1, и password2. Она проверяет, что password1 и password2 совпадают, проверяет пароль с помощью validate_password() и устанавливает пароль пользователя с помощью set_password().

Данные аутентификации в шаблонах

Текущий вошедший в систему пользователь и его разрешения доступны в контексте шаблона при использовании RequestContext.

Технические аспекты

Технически, эти переменные доступны только в контексте шаблона, если вы используете RequestContext и включён процессор контекста 'django.contrib.auth.context_processors.auth'. Он есть в стандартном сгенерированном файле настроек. Для получения дополнительной информации см. документацию RequestContext.

Пользователи

При отрисовке шаблона RequestContext текущий вошедший в систему пользователь, либо экземпляр User, либо экземпляр AnonymousUser, хранится в переменной шаблона {{ user }}:

{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
    <p>Welcome, new user. Please log in.</p>
{% endif %}

Эта переменная контекста шаблона недоступна, если не используется RequestContext.

Разрешения

Разрешения текущего вошедшего в систему пользователя хранятся в переменной шаблона {{ perms }}. Это экземпляр django.contrib.auth.context_processors.PermWrapper, который является удобным для шаблонов псевдонимом разрешений.

Вычисление одноуровневого доступа {{ perms }} как булевого значения является псевдонимом для User.has_module_perms(). Например, чтобы проверить, имеет ли вошедший в систему пользователь какие-либо разрешения в приложении foo:

{% if perms.foo %}

Вычисление двухслойного доступа как булевого значения является псевдонимом для User.has_perm(). Например, чтобы проверить, имеет ли вошедший в систему пользователь разрешение foo.add_vote:

{% if perms.foo.add_vote %}

Вот более полный пример проверки разрешений в шаблоне:

{% if perms.foo %}
    <p>You have permission to do something in the foo app.</p>
    {% if perms.foo.add_vote %}
        <p>You can vote!</p>
    {% endif %}
    {% if perms.foo.add_driving %}
        <p>You can drive!</p>
    {% endif %}
{% else %}
    <p>You don't have permission to do anything in the foo app.</p>
{% endif %}

Также можно выполнить поиск разрешений с помощью {% if in %} выражений. Например:

{% if 'foo' in perms %}
    {% if 'foo.add_vote' in perms %}
        <p>In lookup works, too.</p>
    {% endif %}
{% endif %}

Управление пользователями в админке

При установке django.contrib.admin и django.contrib.auth админка предоставляет удобный способ просмотра и управления пользователями, группами и разрешениями. Пользователи могут создаваться и удаляться как любые модели Django. Группы могут создаваться, а разрешения могут назначаться пользователям или группам. Журнал изменений, внесённых пользователем в модели в админке, также хранится и отображается.

Создание пользователей

Вы должны увидеть ссылку на «Пользователей» в разделе «Авторизация» на главной странице администрирования. Страница администрирования «Добавить пользователя» отличается от стандартных страниц администрирования тем, что требует выбора имени пользователя и пароля перед разрешением редактирования других полей пользователя.

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

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

Изменение паролей

Пароли пользователей не отображаются в администрировании (и не хранятся в базе данных), но отображаются подробности хранения паролей. В отображении этой информации включена ссылка на форму изменения пароля, которая позволяет администраторам менять пароли пользователей.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.0/topics/auth/default/

Spec-Zone.ru

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