使用Django认证系统¶
本文解释了Django的认证系统在默认配置中的用法。这种配置已发展到服务于最常见的项目需求,处理相当广泛的任务,并仔细实施密码和权限。对于身份验证需求与默认值不同的项目,Django支持广泛的身份验证 扩展和定制。
Django认证一起提供认证和授权,并且通常被称为认证系统,因为这些特征有点耦合。
User
对象¶
User
对象是认证系统的核心。它们通常代表与您的网站交互的人,并用于启用诸如限制访问,注册用户配置文件,将内容与创建者关联等。在Django的身份验证框架中只存在一类用户,即 'superusers'
或admin '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管理员,你也可以 以交互方式创建用户。
创建超级用户¶
使用 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
(**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
注解
这是一种认证一组凭证的低级方法;例如,它被
RemoteUserMiddleware
使用。除非你正在编写自己的认证系统,否则你可能不会使用它。相反,如果您正在寻找一种方法来限制对登录用户的访问,请参阅login_required()
装饰器。
权限和授权¶
Django自带一个简单的权限系统。它提供了一种向特定用户和用户组分配权限的方法。
它由Django管理网站使用,但欢迎您在自己的代码中使用它。
Django管理网站使用的权限如下:
查看“添加”表单和添加对象的访问权限限于具有该类型对象的“添加”权限的用户。
访问查看更改列表,查看“更改”窗体和更改对象仅限于具有该类型对象的“更改”权限的用户。
访问删除对象仅限于具有该类型对象的“删除”权限的用户。
权限不仅可以针对每个对象类型设置,还可以针对每个特定的对象实例设置。通过使用 ModelAdmin
类提供的 has_add_permission()
,has_change_permission()
和 has_delete_permission()
方法,可以为同一类型的不同对象实例定制权限。
User
对象有两个多对多字段: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
时创建;第一次在将 django.contrib.auth
添加到 INSTALLED_APPS
后运行 migrate
时,将为所有以前安装的型号以及当时安装的任何新型号创建默认权限。之后,它将为每次运行 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')
Permission
模型很少直接访问。
组¶
django.contrib.auth.models.Group
模型是对用户进行分类的通用方法,因此您可以向这些用户应用权限或其他标签。用户可以属于任意数量的组。
组中的用户自动具有授予该组的权限。例如,如果组 Site editors
具有许可 can_edit_home_page
,则该组中的任何用户都将具有该许可。
除了权限之外,组是一种方便的方式来对用户进行分类,以便为其提供一些标签或扩展功能。例如,您可以创建一个组 'Special users'
,并且您可以编写代码,例如,让他们访问您网站的仅成员部分,或向他们发送仅限成员的电子邮件。
以编程方式创建权限¶
虽然 自定义权限 可以在模型的 Meta
类中定义,但您也可以直接创建权限。例如,您可以为 myapp
中的 BlogPost
模型创建 can_publish
权限:
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_permissions
属性将许可分配给 User
,或者经由其 permissions
属性将该许可分配给 Group
。
权限缓存¶
ModelBackend
在首次访问用户对象以获取权限检查时缓存其权限。这通常适用于请求 - 响应周期,因为通常在添加(例如,在管理员中)之后不立即检查权限。如果您添加权限并在之后立即检查它们,则在测试或视图中,最简单的解决方案是从数据库重新获取用户。例如:
from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404
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_bar')
permission = Permission.objects.get(codename='change_bar')
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_bar') # 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_bar') # True
...
Web请求中的身份验证¶
Django使用 会话 和中间件将认证系统挂接到 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的会话框架将用户的ID保存在会话中。请注意,匿名会话期间的任何数据集在用户登录后保留在会话中。
此示例显示如何使用
authenticate()
和login()
:from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid login' error message. ...
Changed in Django 1.10:在旧版本中,当您手动记录用户时,您在呼叫
login()
之前,must 已成功使用authenticate()
验证用户。现在,您可以使用新的backend
参数设置后端。
选择身份验证后端¶
当用户登录时,用户的ID和用于认证的后端保存在用户的会话中。这允许相同的 认证后端 在将来的请求上提取用户的详细信息。选择在会话中保存的身份验证后端如下:
使用可选的
backend
参数的值(如果提供)。使用
user.backend
属性的值(如果存在)。这允许配对authenticate()
和login()
:authenticate()
在返回的用户对象上设置user.backend
属性。在
AUTHENTICATION_BACKENDS
中使用backend
,如果只有一个。否则,引发异常。
在情况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()
时,当前请求的会话数据将被完全清除。删除所有现有数据。这是为了防止其他人使用相同的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()
执行以下操作:如果用户未登录,请重定向到
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 url(r'^accounts/login/$', auth_views.login),
settings.LOGIN_URL
还接受视图函数名称和 命名的网址格式。这允许您在URLconf中自由重新映射您的登录视图,而无需更新设置。
注解
login_required
装饰器不检查用户的 is_active
标志,但默认的 AUTHENTICATION_BACKENDS
拒绝不活动的用户。
参见
如果您正在为Django admin编写自定义视图(或需要内置视图使用的相同授权检查),您可能会发现 django.contrib.admin.views.decorators.staff_member_required()
装饰器是 login_required()
的有用替代品。
LoginRequired
混音¶
当使用 基于类的视图 时,您可以通过使用 LoginRequiredMixin
实现与 login_required
相同的行为。此混合应该在继承列表中最左边的位置。
-
class
LoginRequiredMixin
¶ - New in Django 1.9.
如果视图正在使用此混合,未经身份验证的用户的所有请求将被重定向到登录页面或显示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
¶ - New in Django 1.9.
当使用 基于类的视图 时,您可以使用
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.can_vote') def my_view(request): ...
与
has_perm()
方法一样,权限名称采用"<app label>.<permission codename>"
格式(即polls
应用程序中模型上的许可权的polls.can_vote
)。装饰器也可以采用可迭代的权限,在这种情况下,用户必须具有所有权限才能访问视图。
注意,
permission_required()
还采用可选的login_url
参数:from django.contrib.auth.decorators import permission_required @permission_required('polls.can_vote', login_url='/loginpage/') def my_view(request): ...
如在
login_required()
装饰器中,login_url
默认为settings.LOGIN_URL
。如果给出了
raise_exception
参数,装饰器将提高PermissionDenied
,提示 the 403 (HTTP Forbidden) view 而不是重定向到登录页面。如果你想使用
raise_exception
,但也给你的用户先登录的机会,你可以添加login_required()
装饰:from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required('polls.can_vote', raise_exception=True) def my_view(request): ...
Changed in Django 1.9:在旧版本中,
permission
参数只处理字符串,列表和元组,而不是字符串和任何可迭代。
PermissionRequiredMixin
混音¶
要对 基于类的视图 应用权限检查,您可以使用 PermissionRequiredMixin
:
-
class
PermissionRequiredMixin
¶ - New in Django 1.9.
这个混合,就像
permission_required
装饰器一样,检查访问视图的用户是否具有所有给定的权限。您应该使用permission_required
参数指定权限(或权限的可迭代):from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = 'polls.can_vote' # Or multiple of permissions: permission_required = ('polls.can_open', 'polls.can_edit')
您可以设置
AccessMixin
的任何参数以自定义未授权用户的处理。您还可以覆盖这些方法:
-
get_permission_required
()¶ 返回mixin使用的权限名称的可迭代。默认为
permission_required
属性,必要时转换为元组。
-
has_permission
()¶ 返回一个布尔值,表示当前用户是否有权执行装饰视图。默认情况下,这返回调用
has_perms()
的结果与get_permission_required()
返回的权限列表。
-
在基于类的视图中重定向未授权的请求¶
为了简化在 基于类的视图 中的访问限制的处理,AccessMixin
可以用于将用户重定向到登录页面或发出HTTP 403禁止响应。
-
class
AccessMixin
¶ - New in Django 1.9.
-
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
()¶ 返回未通过测试的用户将被重定向到的网址。如果设置返回
login_url
,否则返回settings.LOGIN_URL
。
-
get_permission_denied_message
()¶ 当
raise_exception
是True
时,此方法可用于控制传递给错误处理程序的错误消息以显示给用户。默认情况下返回permission_denied_message
属性。
-
get_redirect_field_name
()¶ 返回将包含用户在成功登录后应重定向到的网址的查询参数的名称。如果将此设置为
None
,则不会添加查询参数。默认情况下返回redirect_field_name
属性。
-
handle_no_permission
()¶ 根据
raise_exception
的值,该方法会引发PermissionDenied
异常或将用户重定向到login_url
,如果设置,则可选地包括redirect_field_name
。
-
密码更改时会话无效¶
会话验证已启用,并且在Django 1.10中是强制的(无法禁用它),无论是否启用了 SessionAuthenticationMiddleware
。在旧版本中,此保护仅适用于在 MIDDLEWARE
中启用了 django.contrib.auth.middleware.SessionAuthenticationMiddleware
的情况。
如果您的 AUTH_USER_MODEL
继承自 AbstractBaseUser
或实现其自己的 get_session_auth_hash()
方法,已认证的会话将包括此函数返回的散列。在 AbstractBaseUser
的情况下,这是密码字段的HMAC。 Django验证每个请求的会话中的哈希与请求期间计算的哈希匹配。这允许用户通过更改其密码来注销其所有会话。
django.contrib.auth
管理员中的Django,password_change()
和 user_change_password
视图包含的默认密码更改视图使用新密码哈希更新会话,以便用户更改自己的密码不会自行登出。如果您有自定义密码更改视图并希望具有类似的行为,请使用 update_session_auth_hash()
功能。然而,在这种情况下,如果用户还希望使他们更改密码的会话无效(例如,如果他们认为他们的计算机上的会话cookie被盗),那么他们也需要注销该会话。
-
update_session_auth_hash
(request, user)¶ 此函数接受当前请求和更新的用户对象,从中导出新的会话哈希,并适当地更新会话哈希。用法示例:
from django.contrib.auth import update_session_auth_hash def password_change(request): if request.method == 'POST': form = PasswordChangeForm(user=request.user, data=request.POST) if form.is_valid(): form.save() update_session_auth_hash(request, form.user) else: ...
注解
由于 get_session_auth_hash()
是基于 SECRET_KEY
,更新您的网站以使用新的密钥将使所有现有会话无效。
认证视图¶
Django提供了几个视图,您可以使用它们来处理登录,注销和密码管理。这些使用 股票auth形式,但你也可以传递自己的形式,以及。
Django没有为认证视图提供默认模板。您应该为要使用的视图创建自己的模板。模板上下文记录在每个视图中,请参阅 所有认证视图。
使用视图¶
在项目中实现这些视图有不同的方法。最简单的方法是将提供的URLconf包含在您自己的URLconf中的 django.contrib.auth.urls
中:
urlpatterns = [
url('^', include('django.contrib.auth.urls')),
]
这将包括以下网址格式:
^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^reset/done/$ [name='password_reset_complete']
视图提供了一个URL名称,以方便参考。有关使用命名网址格式的详细信息,请参阅 URL文档。
如果您想要更多地控制网址,可以在URLconf中引用特定视图:
from django.contrib.auth import views as auth_views
urlpatterns = [
url('^change-password/$', auth_views.password_change),
]
视图具有可选参数,可用于更改视图的行为。例如,如果要更改视图使用的模板名称,您可以提供 template_name
参数。一种方法是在URLconf中提供关键字参数,这些将被传递给视图。例如:
urlpatterns = [
url(
'^change-password/$',
auth_views.password_change,
{'template_name': 'change-password.html'}
),
]
所有视图返回一个 TemplateResponse
实例,允许您在渲染之前轻松自定义响应数据。一种方法是在你自己的视图中包装一个视图:
from django.contrib.auth import views
def change_password(request):
template_response = views.password_change(request)
# Do something with `template_response`
return template_response
有关更多详情,请参阅 TemplateResponse文档。
所有认证视图¶
这是一个包含 django.contrib.auth
提供的所有视图的列表。有关实现细节,请参阅 使用视图。
-
login
(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None, redirect_authenticated_user=False)¶ 网址名称:
login
有关使用命名网址格式的详细信息,请参阅 URL文档。
可选参数:
template_name
:要用于记录用户的视图显示的模板的名称。默认为registration/login.html
。redirect_field_name
:包含要在登录后重定向的URL的GET
字段的名称。默认为next
。authentication_form
:用于认证的可调用(通常只是表单类)。默认为AuthenticationForm
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。redirect_authenticated_user
:一个布尔值,用于控制访问登录页面的已验证用户是否将被重定向,就像他们刚刚成功登录一样。默认为False
。警告
如果您启用
redirect_authenticated_user
,其他网站将能够通过请求您的网站上的图片文件的重定向网址来确定他们的访问者是否在您的网站上通过身份验证。为了避免这种“ 社交媒体指纹 ”信息泄露,请将所有图像和您的网站图标托管在单独的域上。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。New in Django 1.10:添加了
redirect_authenticated_user
参数。这里是
django.contrib.auth.views.login
做的:如果通过
GET
调用,它显示POST到同一URL的登录表单。更多关于这一点。如果通过具有用户提交的凭据的
POST
调用,它会尝试将用户登录。如果登录成功,则视图将重定向到next
中指定的URL。如果没有提供next
,它将重定向到settings.LOGIN_REDIRECT_URL
(默认为/accounts/profile/
)。如果登录不成功,它会重新显示登录表单。
您有责任为登录模板提供html,默认情况下称为
registration/login.html
。此模板通过四个模板上下文变量:form
:表示AuthenticationForm
的Form
对象。next
:成功登录后重定向到的URL。这可能还包含查询字符串。site
:当前Site
,根据SITE_ID
设置。如果您没有安装网站框架,这将被设置为RequestSite
的实例,该实例从当前HttpRequest
派生站点名称和域。site_name
:site.name
的别名。如果你没有安装网站框架,这将被设置为request.META['SERVER_NAME']
的值。有关网站的更多信息,请参见 “网站”框架。
如果你不想调用模板
registration/login.html
,你可以通过额外的参数传递template_name
参数到URLconf中的视图。例如,此URLconf行将使用myapp/login.html
:url(r'^accounts/login/$', auth_views.login, {'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()
方法(此方法仅在成功验证表单后调用)。
-
logout
(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None)¶ 记录用户。
网址名称:
logout
可选参数:
next_page
:注销后重定向到的URL。如果未提供,则默认为settings.LOGOUT_REDIRECT_URL
。template_name
:在记录用户之后显示的模板的全名。如果未提供参数,则默认为registration/logged_out.html
。redirect_field_name
:包含在注销后重定向的URL的GET
字段的名称。默认为next
。如果传递给定的GET
参数,则覆盖next_page
URL。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。模板上下文:
title
:本地化的字符串“Logged out”。site
:当前Site
,根据SITE_ID
设置。如果您没有安装网站框架,这将被设置为RequestSite
的实例,该实例从当前HttpRequest
派生站点名称和域。site_name
:site.name
的别名。如果你没有安装网站框架,这将被设置为request.META['SERVER_NAME']
的值。有关网站的更多信息,请参见 “网站”框架。
-
logout_then_login
(request, login_url=None, current_app=None, extra_context=None)¶ 记录用户,然后重定向到登录页面。
网址名称: 未提供默认URL
可选参数:
login_url
:要重定向到的登录页面的URL。如果未提供,则默认为settings.LOGIN_URL
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。
-
password_change
(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None)¶ 允许用户更改其密码。
网址名称:
password_change
可选参数:
template_name
:用于显示密码更改表单的模板的全名。如果未提供,则默认为registration/password_change_form.html
。post_change_redirect
:成功更改密码后重定向的URL。password_change_form
:必须接受user
关键字参数的自定义“更改密码”表单。该表单负责实际更改用户的密码。默认为PasswordChangeForm
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。模板上下文:
form
:密码更改表(见上面的password_change_form
)。
-
password_change_done
(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None)¶ 用户更改其密码后显示的页面。
网址名称:
password_change_done
可选参数:
template_name
:要使用的模板的全名。如果未提供,则默认为registration/password_change_done.html
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。
-
password_reset
(request, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None)¶ 允许用户通过生成一次性使用链接来重置密码,该链接可用于重置密码,并将该链接发送到用户的注册电子邮件地址。
如果系统中不存在提供的电子邮件地址,此视图将不会发送电子邮件,但用户也不会收到任何错误消息。这防止信息泄露给潜在的攻击者。如果在这种情况下要提供错误消息,可以将
PasswordResetForm
子类化并使用password_reset_form
参数。用户被标记为不可用的密码(请参阅
set_unusable_password()
不允许请求重置密码以防止在使用LDAP等外部认证源时发生误操作)。注意,他们不会收到任何错误消息,因为这将暴露其帐户的存在,但没有邮件也将被发送。网址名称:
password_reset
可选参数:
template_name
:用于显示密码重置表单的模板的全名。如果未提供,则默认为registration/password_reset_form.html
。email_template_name
:用于使用重置密码链接生成电子邮件的模板的全名。如果未提供,则默认为registration/password_reset_email.html
。subject_template_name
:用于具有重置密码链接的电子邮件主题的模板的全名。如果未提供,则默认为registration/password_reset_subject.txt
。password_reset_form
:用于获取用户重置密码的电子邮件的表单。默认为PasswordResetForm
。token_generator
:类的实例检查一次性链接。这将默认为default_token_generator
,它是django.contrib.auth.tokens.PasswordResetTokenGenerator
的实例。post_reset_redirect
:成功重置密码后重定向到的网址。from_email
:有效的电子邮件地址。默认情况下,Django使用DEFAULT_FROM_EMAIL
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。html_email_template_name
:用于生成带有密码重置链接的text/html
分段电子邮件的模板的全名。默认情况下,不发送HTML电子邮件。extra_email_context
:电子邮件模板中将提供的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。New in Django 1.9:添加了
extra_email_context
参数。模板上下文:
form
:用于重置用户密码的表单(请参阅上面的password_reset_form
)。
电子邮件模板上下文:
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或httpsuid
:用base64编码的用户主键。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 %}
相同的模板上下文用于主题模板。主题必须是单行纯文本字符串。
-
password_reset_done
(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None)¶ 在用户已通过电子邮件发送重置密码的链接后显示的页面。如果
password_reset()
视图没有设置显式post_reset_redirect
URL,则默认调用此视图。网址名称:
password_reset_done
注解
如果系统中不存在提供的电子邮件地址,用户处于非活动状态或密码不可用,则用户仍将被重定向到此视图,但不会发送电子邮件。
可选参数:
template_name
:要使用的模板的全名。如果未提供,则默认为registration/password_reset_done.html
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。
-
password_reset_confirm
(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None)¶ 提供用于输入新密码的表单。
网址名称:
password_reset_confirm
可选参数:
uidb64
:以64位编码的用户ID。默认为None
。token
:检查密码有效的令牌。默认为None
。template_name
:用于显示确认密码视图的模板的全名。默认值为registration/password_reset_confirm.html
。token_generator
:检查密码的类的实例。这将默认为default_token_generator
,它是django.contrib.auth.tokens.PasswordResetTokenGenerator
的实例。set_password_form
:将用于设置密码的表单。默认为SetPasswordForm
post_reset_redirect
:重置密码后重定向的网址。默认为None
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
模板上下文:
form
:用于设置新用户密码的格式(参见上面的set_password_form
)。validlink
:Boolean,如果链接(uidb64
和token
的组合)有效或未使用,则为True。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。
-
password_reset_complete
(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None)¶ 提供一个视图,通知用户密码已成功更改。
网址名称:
password_reset_complete
可选参数:
template_name
:用于显示视图的模板的全名。默认为registration/password_reset_complete.html
。current_app
:指示哪个应用程序包含当前视图的提示。有关详细信息,请参阅 命名空间的URL解析策略。extra_context
:将被添加到传递给模板的默认上下文数据的上下文数据字典。
1.9 版后已移除:
current_app
参数已弃用,将在Django 2.0中删除。来电者应该设置request.current_app
。
帮助函数¶
-
redirect_to_login
(next, login_url=None, redirect_field_name='next')¶ 重定向到登录页面,然后在成功登录后返回到另一个URL。
必需参数:
next
:成功登录后重定向到的URL。
可选参数:
login_url
:要重定向到的登录页面的URL。如果未提供,则默认为settings.LOGIN_URL
。redirect_field_name
:包含在注销后重定向的URL的GET
字段的名称。如果给定的GET
参数通过,则覆盖next
。
内置表单¶
如果不想使用内置视图,但希望不必为此功能编写表单的方便,认证系统提供了位于 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 forms.ValidationError( _("This account is inactive."), code='inactive', ) if user.username.startswith('b'): raise forms.ValidationError( _("Sorry, accounts starting with 'b' aren't welcome here."), code='no_b_users', )
-
-
class
PasswordChangeForm
¶ 允许用户更改其密码的表单。
-
class
PasswordResetForm
¶ 用于生成并通过电子邮件发送一次性使用链接以重置用户密码的表单。
-
send_email
(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()
使用password_reset()
传递到其电子邮件上下文的相同变量填充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 docs。
用户¶
当呈现模板 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
应用程序中有任何权限,此示例将显示 True
:
{{ perms.foo }}
两级属性查找是 User.has_perm
的代理。如果登录的用户具有 foo.can_vote
权限,则此示例将显示 True
:
{{ perms.foo.can_vote }}
因此,您可以在模板 {% if %}
语句中检查权限:
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.can_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.can_drive %}
<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.can_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
在管理员中管理用户¶
当您同时安装了 django.contrib.admin
和 django.contrib.auth
时,管理员提供了一种方便的方式来查看和管理用户,组和权限。可以像任何Django模型一样创建和删除用户。可以创建组,并且可以将权限分配给用户或组。还存储和显示用户对在管理员内进行的模型进行编辑的日志。
创建用户¶
您应该在主管理员索引页面的“Auth”部分看到“用户”的链接。 “添加用户”管理页面与标准管理页面不同,它要求您在允许您编辑用户字段的其余部分之前选择用户名和密码。
另请注意:如果您希望用户帐户能够使用Django管理网站创建用户,您需要授予他们添加用户 and 更改用户权限(即“添加用户”和“更改用户”权限) 。如果帐户有权添加用户,但不能更改,则该帐户将无法添加用户。为什么?因为如果您有权添加用户,您有权创建超级用户,然后再转而更改其他用户。所以Django需要添加 and 更改权限作为一个小的安全措施。
仔细考虑您如何允许用户管理权限。如果给予非超级用户编辑用户的能力,这最终与给予他们超级用户状态相同,因为他们将能够提升包括他们在内的用户的权限!