Spec-Zone.ru › Django 4.1

Использование системы аутентификации 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 администратор, вы также можете создавать пользователей интерактивно.

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

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

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 Запрещено) вместо перенаправления на страницу входа.

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

END_OF_DOCUMENT_MARKER

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

Представления авторизации

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 перенаправления к файлам изображений на вашем сайте. Чтобы избежать утечки информации «social media fingerprinting», разместите все изображения и 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

Выводит пользователя из системы при POST запросах.

Устарело начиная с версии 4.1: Поддержка выхода из системы при GET запросах устарела и будет удалена в Django 5.0.

Имя 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']. Для более подробной информации о сайтах, см. Модуль “sites”.
logout_then_login(request, login_url=None)

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

Имя URL: Нет URL по умолчанию

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

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

Устарело начиная с версии 4.1: Поддержка выхода из системы при GET запросах устарела и будет удалена в Django 5.0.

class PasswordChangeView

Имя URL: password_change

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

Атрибуты:

template_name

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

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

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

class PasswordResetView

Имя URL: password_reset

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

Этот вид отправит электронное письмо, если выполнены следующие условия:

  • Адрес электронной почты, предоставленный пользователем, существует в системе.
  • Запрашиваемый пользователь активен (User.is_active равен True).
  • У запрашиваемого пользователя есть работоспособный пароль. Пользователи с неработоспособным паролем (см. set_unusable_password()) не могут запросить сброс пароля, чтобы предотвратить злоупотребления при использовании внешнего источника аутентификации, такого как LDAP.

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

Примечание

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

Атрибуты:

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

Полное имя шаблона для создания электронного письма в формате 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']. Для получения дополнительной информации о сайтах, см. Фреймворк «сайты».
  • 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 нет явного success_url 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 ) валидна или еще не использовалась.
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')

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

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

  • 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

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-модель. Группы могут быть созданы, а права могут быть назначены пользователям или группам. Журнал редактирования моделей пользователями, осуществлённых через админпанель, также хранится и отображается.

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

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

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

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

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

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

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

Spec-Zone.ru

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