Использование системы аутентификации Django
В этом документе объясняется использование системы аутентификации Django в конфигурации по умолчанию. Эта конфигурация развивалась с учётом наиболее распространённых потребностей проектов, охватывает довольно широкий круг задач и обеспечивает надёжную реализацию паролей и разрешений. Для проектов, в которых потребности в аутентификации отличаются от стандартных, Django предоставляет широкие возможности для расширения и настройки аутентификации.
Аутентификация Django объединяет аутентификацию и авторизацию и обычно называется системой аутентификации, поскольку эти возможности в некоторой степени связаны.
Объекты User
Объекты User — основа системы аутентификации. Обычно они представляют людей, взаимодействующих с вашим сайтом, и используются для таких задач, как ограничение доступа, регистрация профилей пользователей, связь содержимого с его создателями и т. д. В системе аутентификации Django существует только один класс пользователей: например, 'superusers' или пользователи-администраторы с атрибутом 'staff' — это обычные объекты пользователей с особыми атрибутами, а не объекты отдельных классов пользователей.
Основные атрибуты пользователя по умолчанию:
Полную справочную информацию см. в разделе 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
...\> py 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)[исходный код]
-
aauthenticate(request=None, **credentials) -
Асинхронная версия:
aauthenticate()Используйте
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 использует сессии и промежуточное ПО, чтобы интегрировать систему аутентификации в request objects.
Они предоставляют атрибут request.user и асинхронный метод request.auser для каждого запроса, представляющие текущего пользователя. Если текущий пользователь не вошёл в систему, этому атрибуту будет присвоен экземпляр AnonymousUser, в противном случае — экземпляр User.
Различить их можно с помощью is_authenticated, например:
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
Или в асинхронном представлении:
user = await request.auser()
if user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
Как выполнить вход пользователя
Если у вас есть аутентифицированный пользователь, которого нужно привязать к текущей сессии, используйте функцию login().
-
login(request, user, backend=None)[исходный код]
-
alogin(request, user, backend=None) -
Асинхронная версия:
alogin()Чтобы выполнить вход пользователя из представления, используйте
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. ...
Выбор бэкенда аутентификации
При входе пользователя его идентификатор и бэкенд, использованный для аутентификации, сохраняются в сессии пользователя. Это позволяет тому же бэкенду аутентификации получать сведения о пользователе при последующих запросах. Бэкенд аутентификации, который будет сохранён в сессии, выбирается следующим образом:
- Используется значение необязательного аргумента
backend, если он передан. - Используется значение атрибута
user.backend, если он присутствует. Это позволяет объединитьauthenticate()иlogin():authenticate()задаёт атрибутuser.backendдля возвращаемого объекта пользователя. - Используется
backendизAUTHENTICATION_BACKENDS, если он только один. - В противном случае возникает исключение.
В случаях 1 и 2 значение аргумента backend или атрибута user.backend должно быть строкой с путём импорта через точечную нотацию (как в AUTHENTICATION_BACKENDS), а не самим классом бэкенда.
Как выполнить выход пользователя
-
logout(request)[исходный код]
-
alogout(request) -
Асинхронная версия:
alogout()Чтобы выполнить выход пользователя, вошедшего в систему с помощью
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(f"{settings.LOGIN_URL}?next={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и ваше представление входа правильно связаны. Например, при использовании значений по умолчанию добавьте в конфигурацию URL следующие строки:from django.contrib.auth import views as auth_views path("accounts/login/", auth_views.LoginView.as_view()),settings.LOGIN_URLтакже принимает имена функций-представлений и именованные шаблоны URL. Это позволяет свободно переназначать представление входа в конфигурации URL без необходимости обновлять настройку. - Если пользователь не вошёл в систему, он перенаправляется на
Примечание
Декоратор login_required НЕ проверяет флаг is_active пользователя, однако бэкенды из AUTHENTICATION_BACKENDS по умолчанию отклоняют неактивных пользователей.
См. также
Если вы пишете собственные представления для административного интерфейса Django (или вам нужна та же проверка авторизации, что используется во встроенных представлениях), декоратор django.contrib.admin.views.decorators.staff_member_required() может стать полезной альтернативой login_required().
Миксин LoginRequiredMixin
При использовании представлений на основе классов можно добиться того же поведения, что и с 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 по умолчанию отклоняют неактивных пользователей.
Декоратор login_not_required
Если установлено LoginRequiredMiddleware, все представления по умолчанию требуют аутентификации. Для некоторых представлений, например представления входа, может потребоваться отключить это поведение.
-
login_not_required()[исходный код] -
Разрешает неаутентифицированные запросы к этому представлению, если установлено
LoginRequiredMiddleware.
Ограничение доступа для вошедших в систему пользователей, прошедших проверку
Чтобы ограничить доступ на основе определённых разрешений или другой проверки, можно сделать практически то же, что описано в предыдущем разделе.
Проверку можно выполнить непосредственно для 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, на который будут перенаправлены пользователи, не прошедшие проверку. Это может быть страница входа; если 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): ...Это также предотвращает цикл перенаправлений, когда
redirect_authenticated_user=TrueпредставленияLoginView, а вошедший в систему пользователь не имеет всех необходимых разрешений.
Миксин 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().
-
Представления аутентификации
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 -
URL для перенаправления после входа. По умолчанию используется
LOGIN_REDIRECT_URL.
-
redirect_field_name -
Имя поля
GET, содержащего URL для перенаправления после входа. По умолчанию используетсяnext. Переопределяет URLget_default_redirect_url(), если передан параметрGET.
-
authentication_form -
Вызываемый объект (обычно класс формы), используемый для аутентификации. По умолчанию используется
AuthenticationForm.
-
extra_context -
Словарь контекстных данных, которые будут добавлены к контекстным данным по умолчанию, передаваемым шаблону.
-
redirect_authenticated_user -
Логическое значение, определяющее, следует ли перенаправлять аутентифицированных пользователей, открывающих страницу входа, так, как если бы они только что успешно вошли в систему. По умолчанию —
False.Предупреждение
Если включить
redirect_authenticated_user, другие веб-сайты смогут определить, аутентифицированы ли их посетители на вашем сайте, запросив URL перенаправления к файлам изображений на вашем веб-сайте. Чтобы избежать утечки информации посредством «отпечатка в социальных сетях», размещайте все изображения и значок сайта на отдельном домене.Включение
redirect_authenticated_userтакже может привести к циклу перенаправлений при использовании декоратораpermission_required(), если не используется параметрraise_exception.
-
success_url_allowed_hosts -
setхостов, помимоrequest.get_host(), на которые безопасно перенаправлять после входа в систему. По умолчанию используется пустое значениеset.
-
get_default_redirect_url()[исходный код] -
Возвращает 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. Если приложение sites не установлено, здесь будет экземплярRequestSite, который получает имя сайта и домен из текущего объектаHttpRequest. -
site_name: псевдоним дляsite.name. Если приложение sites не установлено, здесь будет значениеrequest.META['SERVER_NAME']. Подробнее о сайтах см. в разделе Фреймворк «sites».
Если вы предпочитаете не называть шаблон
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.Имя URL:
logoutАтрибуты:
-
next_page -
URL для перенаправления после выхода. По умолчанию используется
LOGOUT_REDIRECT_URL.
-
template_name -
Полное имя шаблона, отображаемого после выхода пользователя из системы. По умолчанию используется
registration/logged_out.html.
-
redirect_field_name -
Имя поля
GET, содержащего URL для перенаправления после выхода из системы. По умолчанию используется'next'. Переопределяет URLnext_page, если передан параметрGET.
-
extra_context -
Словарь контекстных данных, которые будут добавлены к контекстным данным по умолчанию, передаваемым шаблону.
-
success_url_allowed_hosts -
setхостов, помимоrequest.get_host(), на которые безопасно перенаправлять после выхода из системы. По умолчанию используется пустое значениеset.
Контекст шаблона:
-
title: локализованная строка «Вы вышли из системы». -
site: текущийSiteв соответствии с настройкойSITE_ID. Если приложение sites не установлено, здесь будет экземплярRequestSite, который получает имя сайта и домен из текущего объектаHttpRequest. -
site_name: псевдоним дляsite.name. Если приложение sites не установлено, здесь будет значениеrequest.META['SERVER_NAME']. Подробнее о сайтах см. в разделе Фреймворк «sites».
-
-
logout_then_login(request, login_url=None)[исходный код] -
Выполняет выход пользователя из системы при запросах
POST, а затем перенаправляет на страницу входа.Имя URL: URL по умолчанию не задан
Необязательные аргументы:
-
login_url: URL страницы входа, на которую нужно перенаправить. Если не указан, по умолчанию используетсяsettings.LOGIN_URL.
-
-
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. Если приложение sites не установлено, здесь будет значениеrequest.META['SERVER_NAME']. Подробнее о сайтах см. в разделе Фреймворк «sites». -
domain: псевдоним дляsite.domain. Если приложение sites не установлено, здесь будет значение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явно не задан URLsuccess_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[исходный код] -
Форма, используемая в интерфейсе администратора для изменения пароля пользователя. Она также позволяет установить
unusable password, который блокирует вход пользователя с помощью аутентификации по паролю.Принимает
userв качестве первого позиционного аргумента.
-
class AdminUserCreationForm[исходный код] -
Форма, используемая в интерфейсе администратора для создания нового пользователя. Наследуется от
UserCreationForm.Она содержит дополнительное поле
usable_password, включённое по умолчанию. Если включён параметрusable_password, форма проверяет, чтоpassword1иpassword2не пусты и совпадают, проверяет пароль с помощьюvalidate_password()и задаёт пароль пользователя с помощьюset_password(). Если параметрusable_passwordотключён, проверка пароля не выполняется, а аутентификация пользователя по паролю отключается вызовомset_unusable_password().
-
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 BaseUserCreationForm[исходный код] -
ModelFormдля создания нового пользователя. Это рекомендуемый базовый класс, если вам нужно настроить форму создания пользователя.Она содержит три поля:
username(из модели пользователя),password1иpassword2. Форма проверяет, чтоpassword1иpassword2совпадают, проверяет пароль с помощьюvalidate_password()и задаёт пароль пользователя с помощьюset_password().
-
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[исходный код] -
Наследуется от
BaseUserCreationForm. Чтобы предотвратить путаницу с похожими именами пользователей, форма не разрешает имена, отличающиеся только регистром букв.
Данные аутентификации в шаблонах
Текущий вошедший в систему пользователь и его разрешения доступны в контексте шаблона, если вы используете 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» должна быть ссылка «Users». Страница администратора «Add user» отличается от стандартных страниц тем, что для начала редактирования остальных полей пользователя необходимо выбрать имя пользователя и пароль. Кроме того, на этой странице можно выбрать имя пользователя и отключить для него аутентификацию по паролю.
Обратите внимание: если вы хотите, чтобы учётная запись пользователя могла создавать пользователей через сайт администратора Django, необходимо предоставить ей разрешение на добавление пользователей и изменение пользователей (то есть разрешения «Add user» и «Change user»). Если у учётной записи есть разрешение добавлять пользователей, но нет разрешения изменять их, она не сможет добавлять пользователей. Почему? Потому что разрешение на добавление пользователей позволяет создавать суперпользователей, которые затем могут изменять других пользователей. Поэтому Django в качестве дополнительной меры безопасности требует разрешения и на добавление, и на изменение.
Тщательно продумайте, как разрешить пользователям управлять разрешениями. Если предоставить обычному пользователю возможность редактировать пользователей, это фактически равносильно предоставлению ему статуса суперпользователя, поскольку он сможет повышать разрешения пользователей, в том числе свои собственные!
Изменение паролей
Пароли пользователей не отображаются в административном интерфейсе (и не хранятся в базе данных), однако там отображаются сведения о хранении паролей. Среди этой информации есть ссылка на форму смены пароля, которая позволяет администраторам изменить или сбросить пароли пользователей.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/auth/default/