使用 Django 认证系统 — Django 文档
使用 Django 认证系统
本文档解释了 Django 认证系统在其默认配置中的用法。 这种配置已经发展到可以满足最常见的项目需求,处理相当广泛的任务,并仔细实施密码和权限。 对于认证需求与默认不同的项目,Django 支持广泛的 扩展和定制 认证。
Django 身份验证同时提供身份验证和授权,通常称为身份验证系统,因为这些功能有些耦合。
User 物体
User 对象是认证系统的核心。 它们通常代表与您的网站交互的人,用于启用诸如限制访问、注册用户配置文件、将内容与创建者相关联等功能。 Django 的认证框架中只存在一类用户,即 'superusers' 或 admin 'staff' 用户只是设置了特殊属性的用户对象,不是不同类的用户对象。
默认用户的主要属性是:
请参阅 完整 API 文档 以获取完整参考,随后的文档更面向任务。
创建用户
创建用户最直接的方法是使用包含的 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,你还可以【X53X】交互创建用户【X83X】。
创建超级用户
使用 :djadmin:`createsuperuser` 命令创建超级用户:
$ python manage.py createsuperuser --username=joe --email=joe@example.com
系统将提示您输入密码。 输入后,用户将立即创建。 如果您不使用 --username
或 --email
选项,它会提示您输入这些值。
更改密码
Django 不会在用户模型上存储原始(明文)密码,而只会存储散列(有关详细信息,请参阅 密码管理文档 )。 因此,不要试图直接操作用户的密码属性。 这就是创建用户时使用辅助函数的原因。
要更改用户的密码,您有多种选择:
:djadmin:`manage.py 更改密码 *用户名* ` 提供了一种从命令行更改用户密码的方法。 它会提示您更改给定用户的密码,您必须输入两次。 如果两者匹配,新密码将立即更改。 如果您不提供用户,该命令将尝试更改用户名与当前系统用户匹配的密码。
您还可以使用 set_password() 以编程方式更改密码:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
如果您安装了 Django 管理员,您还可以在 身份验证系统的管理页面 上更改用户密码。
Django 还提供了 views 和 forms,可用于允许用户更改自己的密码。
更改用户的密码将注销其所有会话。 有关详细信息,请参阅 更改密码时会话失效 。
验证用户
- 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。
Web 请求中的身份验证
Django 使用 会话 和中间件将身份验证系统挂接到 请求对象 。
这些在代表当前用户的每个请求上提供 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() 在会话中保存用户的 ID,使用 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. ...
选择认证后端
当用户登录时,用户的 ID 和用于身份验证的后端将保存在用户的会话中。 这允许相同的 身份验证后端 在未来的请求中获取用户的详细信息。 要保存在会话中的身份验证后端选择如下:
- 使用可选的
backend
参数的值(如果提供)。 - 使用
user.backend
属性的值(如果存在)。 这允许配对 authenticate() 和 login():authenticate() 在它返回的用户对象上设置user.backend
属性。 - 使用 :setting:`AUTHENTICATION_BACKENDS` 中的
backend
,如果只有一个。 - 否则,引发异常。
在情况 1 和 2 中,backend
参数或 user.backend
属性的值应该是带点的导入路径字符串(就像在 :setting:`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() 时,当前请求的会话数据将被完全清除。 删除所有现有数据。 这是为了防止其他人使用相同的 Web 浏览器登录并访问先前用户的会话数据。 如果您想在注销后立即将任何内容放入用户可用的会话中,请在 after 调用 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() 执行以下操作:
如果用户未登录,则重定向到 :setting:`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
参数,您需要确保 :setting:`settings.LOGIN_URL ` 并且您的登录视图已正确关联。 例如,使用默认值,将以下行添加到您的 URLconf:from django.contrib.auth import views as auth_views path('accounts/login/', auth_views.LoginView.as_view()),
这 :setting:`settings.LOGIN_URL ` 还接受视图函数名称和命名的 URL 模式 . 这允许您在 URLconf 中自由地重新映射您的登录视图,而无需更新设置。
也可以看看
如果您正在为 Django 的管理员编写自定义视图(或需要与内置视图使用相同的授权检查),您可能会发现 django.contrib.admin.views.decorators.staff_member_required() 装饰器login_required()
的有用替代品。
LoginRequired 混合
使用 基于类的视图 时,您可以通过使用 LoginRequiredMixin
实现与 login_required
相同的行为。 这个 mixin 应该在继承列表的最左边的位置。
- class LoginRequiredMixin
如果视图正在使用此 mixin,则未经身份验证的用户的所有请求都将被重定向到登录页面或显示 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
装饰器一样,这个 mixin 不检查用户的 is_active
标志,但默认的 :setting:`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。 它可能是一个登录页面,默认为 :setting:`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()
方法,让 mixin 使用不同命名的函数进行检查(而不是 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_url
默认为 :setting:`settings.LOGIN_URL ` .如果给出
raise_exception
参数,装饰器将引发 PermissionDenied,提示 403 (HTTP Forbidden) 视图 而不是重定向到登录页面。如果你想使用
raise_exception
并且让你的用户有机会先登录,你可以添加 login_required() 装饰器:from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required('polls.add_choice', raise_exception=True) def my_view(request): ...
当 LoginView 的
redirect_authenticated_user=True
和登录用户没有所有必需的权限时,这也避免了重定向循环。
PermissionRequiredMixin 混合
要将权限检查应用于 基于类的视图 ,您可以使用 PermissionRequiredMixin
:
- class PermissionRequiredMixin
这个mixin,就像
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()
返回一个布尔值,表示当前用户是否有权执行装饰视图。 默认情况下,这将返回使用 get_permission_required() 返回的权限列表调用 has_perms() 的结果。
身份验证视图
Django 提供了多个视图,可用于处理登录、注销和密码管理。 这些使用 stock auth 表单 ,但您也可以传递自己的表单。
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
网址名称:
login
有关使用命名 URL 模式的详细信息,请参阅 URL 文档 。
属性:
template_name
:为用于登录用户的视图显示的模板名称。 默认为registration/login.html
。redirect_field_name
:包含登录后重定向到的 URL 的GET
字段的名称。 默认为next
。authentication_form
:用于身份验证的可调用(通常是表单类)。 默认为 AuthenticationForm。extra_context
:上下文数据字典,将添加到传递给模板的默认上下文数据中。redirect_authenticated_user
:一个布尔值,控制访问登录页面的经过身份验证的用户是否将被重定向,就像他们刚刚成功登录一样。 默认为False
。警告
如果您启用
redirect_authenticated_user
,其他网站将能够通过请求重定向 URL 到您网站上的图像文件来确定他们的访问者是否在您的网站上通过了身份验证。 为避免这种“社交媒体指纹识别”信息泄露,请将所有图像和您的网站图标托管在单独的域中。在使用 permission_required() 装饰器时,启用
redirect_authenticated_user
也可能导致重定向循环,除非使用raise_exception
参数。success_url_allowed_hosts
:主机的set
,除了 request.get_host(),登录后重定向是安全的。 默认为空set
。
这是
LoginView
的作用:如果通过
GET
调用,它会显示一个登录表单,该表单发布到相同的 URL。 稍后会详细介绍这一点。如果使用用户提交的凭据通过
POST
调用,它会尝试登录用户。 如果登录成功,则视图重定向到next
中指定的 URL。 如果next
未提供,它重定向到 :setting:`settings.LOGIN_REDIRECT_URL ` (默认为/accounts/profile/
)。 如果登录不成功,它会重新显示登录表单。
您有责任为登录模板提供 html,默认情况下称为
registration/login.html
。 这个模板被传递了四个模板上下文变量:form
:代表 AuthenticationForm 的 Form 对象。next
:登录成功后重定向的URL。 这也可能包含查询字符串。site
:当前站点,根据:setting:`SITE_ID`设置。 如果您没有安装站点框架,这将设置为 RequestSite 的实例,该实例从当前的 HttpRequest 派生站点名称和域。site_name
:site.name
的别名。 如果您没有安装站点框架,这将被设置为 request.META['SERVER_NAME'] 的值。 有关站点的更多信息,请参阅 “站点”框架 。
如果您不想调用模板
registration/login.html
,您可以通过额外的参数将template_name
参数传递给 URLconf 中的as_view
方法。 例如,此 URLconf 行将使用myapp/login.html
代替:path('accounts/login/', auth_views.LoginView.as_view(template_name='myapp/login.html')),
您还可以指定
GET
字段的名称,该字段包含使用redirect_field_name
登录后要重定向到的 URL。 默认情况下,该字段称为next
。这是一个示例
registration/login.html
模板,您可以将其用作起点。 它假设您有一个定义content
块的base.html
模板:{% 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 setup the password_reset view in your URLconf #} <p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}
如果您已自定义身份验证(请参阅 自定义身份验证 ),您可以通过设置
authentication_form
属性来使用自定义身份验证表单。 此表单必须在其__init__()
方法中接受request
关键字参数,并提供一个get_user()
方法,该方法返回经过身份验证的用户对象(此方法仅在成功表单验证后调用) .
- class LogoutView
注销用户。
网址名称:
logout
属性:
next_page
:注销后重定向到的 URL。 默认为 :setting:`settings.LOGOUT_REDIRECT_URL ` .template_name
:用户注销后显示的模板全名。 默认为registration/logged_out.html
。redirect_field_name
:GET
字段的名称,其中包含注销后要重定向到的 URL。 默认为next
。 如果传递给定的GET
参数,则覆盖next_page
URL。extra_context
:上下文数据字典,将添加到传递给模板的默认上下文数据中。success_url_allowed_hosts
:除 request.get_host() 之外的set
主机,注销后重定向是安全的。 默认为空set
。
模板上下文:
title
:字符串“Logged out”,本地化。site
:当前站点,根据:setting:`SITE_ID`设置。 如果您没有安装站点框架,这将设置为 RequestSite 的实例,该实例从当前的 HttpRequest 派生站点名称和域。site_name
:site.name
的别名。 如果您没有安装站点框架,这将被设置为 request.META['SERVER_NAME'] 的值。 有关站点的更多信息,请参阅 “站点”框架 。
- logout_then_login(request, login_url=None)
注销用户,然后重定向到登录页面。
URL 名称: 未提供默认 URL
可选参数:
login_url
:要重定向到的登录页面的 URL。 默认为 :setting:`settings.LOGIN_URL ` 如果没有提供。
- class PasswordChangeView
网址名称:
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
网址名称:
password_change_done
用户更改密码后显示的页面。
属性:
template_name
:要使用的模板的全名。 如果未提供,则默认为registration/password_change_done.html
。extra_context
:上下文数据字典,将添加到传递给模板的默认上下文数据中。
- class PasswordResetView
网址名称:
password_reset
允许用户通过生成可用于重置密码的一次性使用链接并将该链接发送到用户注册的电子邮件地址来重置其密码。
如果系统中不存在提供的电子邮件地址,则此视图不会发送电子邮件,但用户也不会收到任何错误消息。 这可以防止信息泄露给潜在的攻击者。 如果您想在这种情况下提供错误消息,您可以子类化 PasswordResetForm 并使用
form_class
属性。笔记
请注意,发送电子邮件会花费额外的时间,因此您可能容易受到电子邮件地址枚举计时攻击的影响,因为现有电子邮件地址的重置请求持续时间与不存在的电子邮件地址的重置请求持续时间之间存在差异. 为了减少开销,您可以使用允许异步发送电子邮件的第 3 方包,例如 django-mailer。
使用不可用密码标记的用户(请参阅 set_unusable_password() 不允许在使用外部身份验证源(如 LDAP)时请求重置密码以防止误用。 请注意,他们不会收到任何错误消息,因为这会暴露他们帐户的存在,但也不会发送任何邮件。
属性:
template_name
:用于显示密码重置表单的模板的全名。 如果未提供,则默认为registration/password_reset_form.html
。form_class
:用于获取用户的电子邮件以重置密码的表单。 默认为 PasswordResetForm。email_template_name
:用于生成带有重置密码链接的电子邮件的模板的全名。 如果未提供,则默认为registration/password_reset_email.html
。subject_template_name
:用于带有重置密码链接的电子邮件主题的模板的全名。 如果未提供,则默认为registration/password_reset_subject.txt
。token_generator
:检查一次性链接的类的实例。 这将默认为default_token_generator
,它是django.contrib.auth.tokens.PasswordResetTokenGenerator
的一个实例。success_url
:密码重置请求成功后重定向到的 URL。 默认为'password_reset_done'
。from_email
:有效的电子邮件地址。 默认情况下,Django 使用 :setting:`DEFAULT_FROM_EMAIL`。extra_context
:上下文数据字典,将添加到传递给模板的默认上下文数据中。html_email_template_name
:用于生成带有密码重置链接的 text/html 多部分电子邮件的模板的全名。 默认情况下,不发送 HTML 电子邮件。extra_email_context
:电子邮件模板中可用的上下文数据字典。 它可用于覆盖下面列出的默认模板上下文值,例如domain
。
模板上下文:
form
:用于重置用户密码的表单(见上文form_class
)。
电子邮件模板上下文:
email
:user.email
的别名user
:当前用户,根据email
表单域。 只有活跃用户才能重置他们的密码 (User.is_active is True
)。site_name
:site.name
的别名。 如果您没有安装站点框架,这将被设置为 request.META['SERVER_NAME'] 的值。 有关站点的更多信息,请参阅 “站点”框架 。domain
:site.domain
的别名。 如果您没有安装站点框架,这将被设置为request.get_host()
的值。protocol
:http 或 httpsuid
:用户的主键以 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
网址名称:
password_reset_done
用户通过电子邮件收到重置密码链接后显示的页面。 如果 PasswordResetView 没有明确的
success_url
URL 集,则默认调用此视图。笔记
如果系统中不存在提供的电子邮件地址、用户处于非活动状态或密码不可用,用户仍将被重定向到此视图,但不会发送电子邮件。
属性:
template_name
:要使用的模板的全名。 如果未提供,则默认为registration/password_reset_done.html
。extra_context
:上下文数据字典,将添加到传递给模板的默认上下文数据中。
- class PasswordResetConfirmView
网址名称:
password_reset_confirm
显示用于输入新密码的表单。
来自 URL 的关键字参数:
uidb64
:以 base 64 编码的用户 ID。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
,则在对用户进行身份验证时使用的身份验证后端的虚线路径。 仅当您配置了多个 :setting:`AUTHENTICATION_BACKENDS` 时才需要。 默认为None
。form_class
:用于设置密码的表格。 默认为 SetPasswordForm。success_url
:密码重置完成后重定向的 URL。 默认为'password_reset_complete'
。extra_context
:上下文数据字典,将添加到传递给模板的默认上下文数据中。reset_url_token
:作为密码重置 URL 组件显示的令牌参数。 默认为'set-password'
。
模板上下文:
form
:用于设置新用户密码的表单(见上文form_class
)。validlink
:布尔值,如果链接(uidb64
和token
的组合)有效或尚未使用,则为真。
- class PasswordResetCompleteView
网址名称:
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。 默认为 :setting:`settings.LOGIN_URL ` 如果没有提供。redirect_field_name
:GET
字段的名称,其中包含注销后要重定向到的 URL。 如果传递给定的GET
参数,则覆盖next
。
内置表格
如果您不想使用内置视图,但希望不必为此功能编写表单的便利,身份验证系统提供了几个位于 django.contrib.auth.forms[ 的内置表单] X221X]:
笔记
内置的身份验证表单对它们正在使用的用户模型做出了某些假设。 如果您使用 自定义用户模型 ,则可能需要为身份验证系统定义您自己的表单。 有关更多信息,请参阅有关 使用带有自定义用户模型的内置身份验证表单 的文档。
- 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()
使用 PasswordResetView 传递给其电子邮件上下文的相同变量填充context
。
- 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 实例)存储在模板变量 [ X192X]:
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
如果未使用 RequestContext
,则此模板上下文变量不可用。
权限
当前登录用户的权限存储在模板变量模板:Perms
中。 这是django.contrib.auth.context_processors.PermWrapper
的一个实例,它是一个模板友好的权限代理。
将 模板:Perms
的单属性查找评估为布尔值是 User.has_module_perms() 的代理。 例如,要检查登录用户在 foo
应用程序中是否有任何权限:
{% if perms.foo %}
将两级属性查找评估为布尔值是 User.has_perm() 的代理。 例如,检查登录用户是否有权限foo.add_vote
:
{% if perms.foo.add_vote %}
这是检查模板中权限的更完整示例:
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.add_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.add_driving %}
<p>You can drive!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the foo app.</p>
{% endif %}
也可以通过 {% if in %}
语句查找权限。 例如:
{% if 'foo' in perms %}
{% if 'foo.add_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
在管理员中管理用户
当您同时安装了 django.contrib.admin
和 django.contrib.auth
时,管理员提供了一种查看和管理用户、组和权限的便捷方式。 可以像任何 Django 模型一样创建和删除用户。 可以创建组,并且可以为用户或组分配权限。 还会存储和显示用户在管理员中对模型进行编辑的日志。
创建用户
您应该会在主管理索引页面的“身份验证”部分中看到指向“用户”的链接。 “添加用户”管理页面与标准管理页面不同,它要求您在允许您编辑用户的其余字段之前选择用户名和密码。
另请注意:如果您希望用户帐户能够使用 Django 管理站点创建用户,则需要授予他们添加用户 和 更改用户的权限(即,“添加用户”和“更改用户”权限)。 如果帐户有权添加用户但不能更改用户,则该帐户将无法添加用户。 为什么? 因为如果您有权添加用户,您就有权创建超级用户,然后又可以更改其他用户。 因此,Django 需要添加 和 更改权限作为轻微的安全措施。
考虑如何允许用户管理权限。 如果您赋予非超级用户编辑用户的能力,这最终与赋予他们超级用户身份相同,因为他们将能够提升包括他们自己在内的用户的权限!