这篇文档解释默认配置下Django认证系统的使用。 这些配置已经逐步可以满足大部分常见项目的需要,可以处理范围非常广泛的任务,且具有一套细致的密码和权限实现。 对于需要与默认配置不同需求的项目,Django支持extension and customization认证。
Django的认证同时提供认证和授权,并通常统一称为认证系统,因为这些功能某些地方是耦合的。
User
对象¶User
对象是认证系统的核心。 它们通常表示与你的站点进行交互的用户,并用于启用限制访问、注册用户信息和给创建者关联内容等。 在Django的认证框架中只存在一种类型的用户,因此诸如'superusers'
或管理员'staff'
用户只是具有特殊属性集的user对象,而不是不同类型的user对象。
默认user的基本属性有:
完整的参考请参阅full API documentation
,以下的内容更偏重特定的任务。
创建users最直接的方法是使用create_user()
辅助函数:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
# 到这里,user 这一个User对象已经保存于
# 数据库中了。 # 你可以继续修改它的属性。
# 如果你想要修改其他字段。
>>> user.last_name = 'Lennon'
>>> user.save()
如果你已经安装了Django admin,你也可以create users interactively.
使用createsuperuser
命令创建superusers:
$ python manage.py createsuperuser --username=joe --email=joe@example.com
将会提示你输入一个密码。 在你输入一个密码后,该user将会立即创建。 如果您离开--username
或--email
选项,它将提示您输入这些值。
Django不会在user模型上存储原始的(明文)密码,而只是一个哈希(完整的细节参见documentation of how passwords are managed)。 因为这个原因,不要尝试直接操作user的password属性。 这也是为什么创建一个user时要使用辅助函数。
若要修改一个用户的密码,你有几种选择:
manage.py changepassword *username*
提供了一种从命令行更改用户密码的方法。 它提示你修改一个给定user的密码,你必须输入两次。 如果它们匹配,新的密码将会立即修改。 如果你没有提供user,命令行将尝试修改与当前系统用户匹配的用户名的密码。
你也可以通过程序修改密码,使用set_password()
:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
如果你安装了Django admin,你还可以在authentication system’s admin pages修改user的密码。
Django还提供views和forms用于允许user修改他们自己密码。
更改用户密码将会注销所有会话。 详细信息请参阅Session invalidation on password change。
authenticate
(request=None, **credentials)[source]¶使用authenticate()
来验证一组凭据。 它以credentials为关键字参数,默认为username
和password
,根据每个认证的后端进行检查,如果credentials对某个后端有效则返回一个User
对象。 如果credentials对任何后端都无效,或者如果后端引发了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()
方法上传递。
添加了可选的request
参数。
注
这是一种低级别的方式来验证一组凭据;例如,它由RemoteUserMiddleware
使用。 除非你正在编写你自己的认证系统,否则你可能不会使用到它。 相反,如果您正在寻找一种方法来限制对登录用户的访问,请参阅login_required()
装饰器。
Django本身提供了一个简单的权限系统。 它提供了一种为特定用户和用户组分配权限的方法。
它被Django的admin站点使用,但欢迎你在你自己的代码中使用。
Django admin 站点使用如下的权限:
权限不但可以根据每个对象的类型,而且可以根据特定的对象实例设置。 通过使用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模型创建3个默认的权限 – add、change和delete。
当你运行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'
,然后你可以这样写代码,给他们访问你的站点仅限会员的部分,或者给他们发仅限于会员的邮件。
虽然custom permissions可以定义在模型的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
。
在第一次获取权限用于检查后,模型的后端
将在该用户对象上缓存这些权限。 这对于常见的请求-响应周期通常没问题,因为通常在添加权限后不会立即检查权限(例如在管理后台中)。 如果你要添加权限并立即检查它们,例如在测试中或视图中,最简单的解决方案是从数据库重新获取用户。 像这样:
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from myapp.models import BlogPost
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('myapp.change_blogpost')
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.get(
codename='change_blogpost',
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_blogpost') # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm('myapp.change_blogpost') # True
...
它们在每个请求上提供一个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)[source]¶从视图中登入一个用户,请使用login()
。 它接受一个HttpRequest
对象和一个User
对象。
login()
使用Django的session框架来将用户的ID保存在session中。
请注意,匿名会话期间的任何数据集在用户登录后都会保留在会话中。
下面的示例向你演示如何使用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.
...
在旧版本中,当你手工登陆一个用户时,在调用login()
之前必须用authenticate()
成功认证这个用户。 现在你可以使用新的backend
参数设置后端。
用户登录时,用户的ID和用于身份验证的后端保存在用户的会话中。 这允许相同的身份验证后端在将来的请求中获取用户的详细信息。 要保存在会话中的认证后端选择如下:
backend
参数的值(如果提供)。user.backend
属性的值(如果存在)。 这允许配对authenticate()
和login()
:authenticate()
设置user.backend
属性用户对象返回。AUTHENTICATION_BACKENDS
中的backend
。在情况1和2中,backend
参数或user.backend
属性的值应为点号导入路径字符串(如AUTHENTICATION_BACKENDS
的字符串),而不是实际的类。
logout
(request)[source]¶若要登出一个已经通过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浏览器登入并访问前一个用户的会话数据。 如果你想在用户登出之后可以立即访问放入会话中的数据,请在调用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)[source]¶作为一个快捷方式,你可以使用便捷的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
,你非常可能同时需要自定义你的登录模板,因为存储重定向路径的模板上下文变量将使用"next"
值作为它的键,而不是默认的redirect_field_name
。
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.LoginView.as_view()),
settings.LOGIN_URL
同时还接收视图函数名和named URL patterns。 这允许你自由地重新映射你的URLconf中的登录视图而不用更新设置。
注
login_required
装饰器不会在用户上检查is_active
标志,但默认的AUTHENTICATION_BACKENDS
拒绝不活动的用户。
请参见
如果您正在为Django的管理员编写自定义视图(或需要相同的授权检查内置视图使用),您可能会发现django.contrib.admin.views.decorators.staff_member_required()
装饰器对login_required()
来说是一个有用的替代方法。
LoginRequired
mixin¶使用class-based views时,可以使用LoginRequiredMixin
实现与login_required
相同的行为。 此mixin应位于继承列表中最左侧的位置。
LoginRequiredMixin
¶如果视图正在使用此mixin,那么根据raise_exception
参数,未经身份验证的用户的所有请求将被重定向到登录页面或显示HTTP 403 Forbidden错误。
您可以设置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
标志,但默认的AUTHENTICATION_BACKENDS
拒绝不活动的用户。
要根据某些权限或某些其他测试来限制访问权限,您可以执行与上一节中所述基本相同的操作。
简单的方法就是在视图中直接运行你对request.user
的测试。 例如,视图检查用户的邮件属于特定的地址(例如@example.com),若不是,则重定向到登录页面。
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')[source]¶你可以用方便的 False
装饰器,当回调函数返回 user_passes_test
时会执行一个重定向操作:
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
settings.LOGIN_URL
。redirect_field_name
login_required()
的参数相同。
把它设置为 None
来把它从 URL 中移除,当你想把通不过检查的用户重定向到没有next page 的非登录页面时。像这样:
@user_passes_test(email_check, login_url='/login/')
def my_view(request):
...
UserPassesTestMixin
¶当使用class-based views时,可以使用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)[source]¶检查一个用户是否有指定的权限是相对常见的需求。 为此,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.can_vote
表示polls
应用中一个模型的权限)。
装饰器也可以采取可迭代的权限,在这种情况下,用户必须具有所有权限才能访问视图。
请注意,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):
...
PermissionRequiredMixin
mixin ¶要对class-based views应用权限检查,可以使用PermissionRequiredMixin
:
PermissionRequiredMixin
¶这个mixin,就像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
()¶返回一个布尔值,表示当前用户是否具有执行装饰视图的权限。 默认情况下,返回使用get_permission_required()
返回的权限列表调用has_perms()
的结果。
为了简化在class-based views中处理访问限制,可以使用AccessMixin
将用户重定向到登录页面或发出HTTP 403 Forbidden响应。
AccessMixin
¶login_url
¶Default return value for get_login_url()
. 默认为None
,在这种情况下,get_login_url()
返回到settings.LOGIN_URL
。
permission_denied_message
¶Default return value for get_permission_denied_message()
.
默认为空字符串。
redirect_field_name
¶Default return value for get_redirect_field_name()
. 默认为"next"
。
raise_exception
¶如果此属性设置为True
,将会引发PermissionDenied
异常,而不是重定向。 默认为False
。
get_login_url
()¶返回未通过测试的用户将被重定向到的URL。 如果设置了login_url
,则返回它,否则返回settings.LOGIN_URL
。
get_permission_denied_message
()¶当raise_exception
是True
时,此方法可用于控制传递给错误处理程序以显示给用户的错误消息。 默认返回permission_denied_message
属性。
get_redirect_field_name
()¶返回在成功登录后将包含用户应重定向到的URL的查询参数的名称。 如果将其设置为None
,则不会添加查询参数。 默认返回redirect_field_name
属性。
handle_no_permission
()¶根据raise_exception
的值,该方法会引发PermissionDenied
异常,或将用户重定向到login_url
,可选地包括redirect_field_name
如果设置。
Django 1.10中启用了会话验证并且是强制的(无法禁用它),无论是否启用了SessionAuthenticationMiddleware
。 在旧版本中,只有在MIDDLEWARE
中启用django.contrib.auth.middleware.SessionAuthenticationMiddleware
时,此保护才适用。
如果你的AUTH_USER_MODEL
继承自AbstractBaseUser
,或者实现了它自己的get_session_auth_hash()
方法,验证后的会话会包含这个函数返回的哈希值。
在AbstractBaseUser
的情况中,这是密码字段的HMAC。 Django验证每个请求的会话中的哈希与请求期间计算的哈希是一致的。 这允许用户通过修改密码来登出所有的会话。
Django包含的默认密码修改视图PasswordChangeView
和django.contrib.auth
中的user_change_password
视图中,使用新的密码哈希更新会话,以便用户更改自己的密码不会自动登出。 如果你有自定义的密码更改视图并希望具有类似的行为,请使用update_session_auth_hash()
函数。
update_session_auth_hash
(request, user)[source]¶这个函数接受当前请求和更新后的用户对象,获取新的会话哈希并更新会话中的哈希为正确的值。 它还会改变会话的键,以使被盗会话cookie无效。
使用示例:
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 提供一些视图,你可以用来处理登录、登出和密码管理。 它们使用stock auth forms,但你也可以传递你自己的表单。
Django 没有为认证视图提供默认的模板。 你应该为你想要使用的视图创建自己的模板。 模板的上下文定义在每个视图中,参见All authentication views.
有几种不同的方法在你的项目中使用这些视图。 最简单的方法是包含django.contrib.auth.urls
中提供的URLconf到你自己的URLconf中,例如
urlpatterns = [
url('^', include('django.contrib.auth.urls')),
]
这将包含进下面的URL模式:
^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模式的细节请参见the URL documentation。
如果你想更多地控制你的URL,你可以在你的URLconf中引用一个特定的视图:
from django.contrib.auth import views as auth_views
urlpatterns = [
url('^change-password/$', auth_views.PasswordChangeView.as_view()),
]
这些视图具有可选的参数,你可以用来改变视图的行为。 例如,如果你想修改一个视图使用的模板名称,你可以提供template_name
参数。 一种方法是在URLconf 中提供关键字参数,它们将被传递到视图中。 像这样:
urlpatterns = [
url(
'^change-password/$',
auth_views.PasswordChangeView.as_view(template_name='change-password.html'),
),
]
所有视图都是 基于类的, 这允许你很容易通过子类化来定制它们。
下面列出了django.contrib.auth
提供的所有视图。 实现细节参见Using the views。
login
(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None, redirect_authenticated_user=False)¶自1.11版以来已弃用 基于函数的login
视图应该被基于类的LoginView
替代。
该视图的可选参数与基于类的LoginView
属性类似。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
属性已弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
。
添加了redirect_authenticated_user
参数。
LoginView
¶URL名称: login
使用命名URL模式的细节请参见the URL documentation。
属性:
template_name
:要显示用于登录用户的视图的模板的名称。 默认为registration/login.html
。
redirect_field_name
:包含登录后要重定向到的URL的GET
字段的名称。 默认为next
。
authentication_form
:用于认证的可调用对象(通常只是一个表单类)。 默认为AuthenticationForm
。
extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。
redirect_authenticated_user
:一个布尔值,用于控制访问登录页面的已验证用户是否将被重定向,就像他们刚刚成功登录一样。 默认为False
。
警告
如果您启用了redirect_authenticated_user
,其他网站将能够通过请求重定向到网站上的图像文件来确定访问者是否在您的网站上进行身份验证。 To avoid
this “social media fingerprinting” information
leakage, host all images and your favicon on a separate domain.
success_url_allowed_hosts
:一个主机名的set(集合)
,除了request.get_host()
之外,可以在登录后安全地重定向到它们。 默认为空set
。
这是LoginView
所做的事情:
GET
调用,它显示一个POST给相同URL的登录表单。 后面有更多这方面的信息。POST
调用并带有用户提交的凭证,它会尝试登入该用户。 如果登入成功,该视图重定向到next
中指定的URL。 如果未提供next
,则会重定向到settings.LOGIN_REDIRECT_URL
(默认为/accounts/profile/
)。 如果登入不成功,则重新显示登录表单。你需要提供html模板给login,默认调用registration/login.html
。 模板会得到4个模板上下文变量:
form
:表示AuthenticationForm
的Form
对象。next
:成功登录后重定向到的URL。 它还可能包含一个查询字符串。site
:根据SITE_ID
设置,当前Site
。 如果您没有安装站点框架,则将设置为RequestSite
的实例,该实例从当前的HttpRequest
派生站点名称和域。site_name
:site.name
的别名。 如果你没有安装site框架,这将被设置成request.META['SERVER_NAME']
的值。
关于site 的更多信息,参见The “sites” framework。如果您不想调用模板registration/login.html
,您可以通过额外的参数将template_name
参数传递给as_view
你的URLconf中的方法。 例如,下面URLconf中的行将使用myapp/login.html
:
url(r'^accounts/login/$', auth_views.LoginView.as_view(template_name='myapp/login.html')),
您还可以使用redirect_field_name
指定包含要重定向到的URL的GET
字段的名称。 默认情况下,该字段叫做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 %}
如果您有自定义身份验证(请参阅Customizing Authentication),您可以通过设置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)¶自1.11版以来已弃用 基于函数的logout
视图应该被基于类的LogoutView
替代。
该视图的可选参数类似于基于类的LogoutView
属性。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
属性已弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
替代。
LogoutView
¶登出一个用户。
URL名称: logout
属性:
next_page
:注销后重定向到的URL。 默认为settings.LOGOUT_REDIRECT_URL
。template_name
:记录用户后显示的模板的全名。 默认为registration/logged_out.html
。redirect_field_name
:包含要注销后重定向到的URL的GET
字段的名称。 默认为next
。 如果提供了GET
参数,会覆盖next_page
URL。extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。success_url_allowed_hosts
:除了request.get_host()
之外,主机的set
可以在注销后重定向安全。 默认为空set
。模板上下文:
title
:字符串“Logged out”,本地化。site
:根据SITE_ID
设置,当前Site
。 如果您没有安装站点框架,则将设置为RequestSite
的实例,该实例从当前的HttpRequest
派生站点名称和域。site_name
:site.name
的别名。 如果你没有安装site框架,这将被设置成request.META['SERVER_NAME']
的值。
关于site 的更多信息,参见The “sites” framework。logout_then_login
(request, login_url=None, current_app=None, extra_context=None)¶登出一个用户,然后重定向到登录页面。
URL名称: 没有提供默认的URL
可选参数:
login_url
:要重定向到的登录页面的URL。
如果没有提供,默认为settings.LOGIN_URL
。current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
替代。
自1.11版以来已弃用 未使用的extra_context
参数已被弃用,将在Django 2.1中删除。
password_change
(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None)¶自1.11版以来已弃用 基于功能的password_change
视图应该被基于类的PasswordChangeView
替代。
除了post_change_redirect
和password_change_form
参数之外,该视图的可选参数类似于基于类的PasswordChangeView
属性,它们映射到success_url
和form_class
属性的基于类的视图。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
替代。
PasswordChangeView
¶URL名称: password_change
允许一个用户修改他的密码。
属性:
template_name
:用于显示密码更改表单的模板的全名。 如果没有提供,默认为registration/password_change_form.html
。success_url
:成功更改密码后重定向到的URL。form_class
:需要接受user
关键字参数的自定义“更改密码”表单。 表单用于实际修改用户密码。 默认为 PasswordChangeForm
。extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。模板上下文:
form
:密码更改表单(见上面的form_class
)。password_change_done
(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None)¶自1.11版以来已弃用 基于函数的password_change_done
视图应该被基于类的PasswordChangeDoneView
替代。
此视图的可选参数与基于类的PasswordChangeDoneView
属性类似。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
替代。
PasswordChangeDoneView
¶URL名称: password_change_done
这个页面在用户修改密码之后显示。
属性:
template_name
:要使用的模板的全名。
如果没有提供,默认为registration/password_change_done.html
。extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。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)¶自1.11版以来已弃用 基于功能的password_reset
视图应该被基于类的PasswordResetView
替代。
这个视图的可选参数,都类似于基于类的PasswordResetView
的属性, 除了 the post_reset_redirect
和password_reset_form
参数,这些参数映射基于类的视图的success_url
和 form_class
属性。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
。
PasswordResetView
¶网址名称: password_reset
允许用户通过生成一次性的连接并发送到用户注册的邮箱地址中来重置密码。
如果提供的邮箱地址不在系统中存在,这个视图不会发送任何邮件,但是用户也不会收到任何错误信息。
这会阻止数据泄露给潜在的攻击者。 如果要在这种情况下提供错误消息,您可以继承PasswordResetForm
并使用form_class
属性。
用无效密码标记的用户(参见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
:类的实例检查一次性链接。
默认为django.contrib.auth.tokens.PasswordResetTokenGenerator
,它是 default_token_generator
的一个实例。success_url
:在成功的密码重置请求后重定向到的URL。from_email
:有效的电子邮件地址。 默认情况下Django 使用DEFAULT_FROM_EMAIL
。extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。html_email_template_name
:用于生成具有密码重置链接的text/html
多部分电子邮件的模板的全名。 默认情况下,不发送HTML电子邮件。extra_email_context
:将在电子邮件模板中可用的上下文数据字典。模板上下文:
form
:用于重置用户密码的窗体(见form_class
)。邮件模板上下文:
email
:user.email
的别名user
:根据email
表单字段,当前User
。 只有有效用户才能重置其密码(User.is_active 是 True
)。site_name
:site.name
的别名。 如果你没有安装site框架,这将被设置成request.META['SERVER_NAME']
的值。
关于site 的更多信息,参见The “sites” framework。domain
:site.domain
的别名。 如果您没有安装网站框架,则会将其设置为request.get_host()
的值。protocol
:http或httpsuid
:用户的主键编码在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 %}
主题模板使用了同样的模板上下文。 主题必须是单行的纯文本字符串。
password_reset_done
(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None)¶自1.11版以来已弃用 基于功能的password_reset_done
视图应该被基于类的PasswordResetDoneView
替代。
此视图的可选参数类似于基于类的PasswordResetDoneView
属性。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
。
PasswordResetDoneView
¶网址名称: password_reset_done
这个页面在向用户发送重置密码的邮件后展示。 如果PasswordResetView
没有明确的success_url
URL设置,默认情况下会调用此视图。
注
如果提供的email地址在系统中不存在,用户未激活,或者密码不可用,用户仍然会重定向到这个视图,但是不会发送邮件。
属性:
template_name
:要使用的模板的全名。
如果未提供,默认为registration/password_reset_done.html
。extra_context
:将添加到传递给模板的默认上下文数据的上下文数据字典。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)¶自1.11版以来已弃用 基于功能的password_reset_confirm
视图应该由基于类的PasswordResetConfirmView
代替。
该视图的可选参数与基于类的PasswordResetConfirmView
属性类似,除了post_reset_redirect
和set_password_form
参数,它们映射到success_url
和form_class
属性的基于类的视图。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
。
PasswordResetConfirmView
¶URL名称: password_reset_confirm
为输入新密码展示表单。
网址的关键字参数:
uidb64
:用户的ID编码在64位。token
:令牌来检查密码是否有效。属性:
template_name
:显示确认密码视图的模板的全名。 默认值为registration/password_reset_confirm.html
。token_generator
:检查密码的类的实例。 默认为django.contrib.auth.tokens.PasswordResetTokenGenerator
,它是 default_token_generator
的一个实例。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
:将添加到传递给模板的默认上下文数据的上下文数据字典。模板上下文:
form
:用于设置新用户密码的窗体(见set_password_form
)。validlink
:Boolean,如果链接(uidb64
和token
的组合)有效或未使用,则为True。password_reset_complete
(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None)¶自1.11版以来已弃用 基于功能的password_reset_complete
视图应该被基于类的PasswordResetCompleteView
替代。
该视图的可选参数类似于基于类的PasswordResetCompleteView
属性。 另外,它有:
current_app
:指示哪个应用程序包含当前视图的提示。 更多信息参见namespaced URL resolution strategy。自1.9版以来已弃用 current_app
参数已被弃用,将在Django 2.0中删除。 调用者应该设置request.current_app
。
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。
如果没有提供,默认为settings.LOGIN_URL
。redirect_field_name
:包含要注销后重定向到的URL的GET
字段的名称。 如果传递给定的GET
参数,则覆盖next
。如果你不想用内建的视图,但是又不想编写针对该功能的表单,认证系统提供了几个内建的表单,位于django.contrib.auth.forms
:
注
内建的验证表单对它们处理的用户模型做了特定假设。 如果您使用custom user model,则可能需要为身份验证系统定义自己的表单。 更多信息请见using the built-in authentication forms with custom user models的文档。
AdminPasswordChangeForm
¶Admin 站点中使用的表单,用于修改用户密码。
接受user
作为第一个参数。
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.用户名.startswith('b'):
raise forms.ValidationError(
_("Sorry, accounts starting with 'b' aren't welcome here."),
code='no_b_users',
)
PasswordChangeForm
¶用于用户修改密码的表单。
PasswordResetForm
¶用于生成并邮件发送重置密码的一个一次性链接的表单。
send_email
(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)¶使用这些参数来发送EmailMultiAlternatives
。
可以覆盖这个方法,来自定义邮件如何发送给用户。
参数: |
|
---|
默认情况下,save()
将PasswordResetView
传递给其电子邮件上下文的相同变量填充context
。
SetPasswordForm
¶允许用户不输入旧密码修改密码的表单。
UserChangeForm
¶Admin 站点中使用的表单,用于修改用户信息和权限。
UserCreationForm
¶用于创建新用户的ModelForm
。
它有三个字段:username
(来自用户型号),password1
和password2
。 验证password1
和password2
匹配,使用validate_password()
验证密码,并使用set_password()
当你使用RequestContext
时,当前登入的用户和它们的权限在template context中可以访问。
技术细节
技术上讲,这些变量只有在你使用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.auth
和django.contrib.admin
这两个你都安装了,将可以通过admin方便地查看和管理用户、组和权限。 可以像其它任何Django模型一样创建和删除用户。 可以创建组,并分配权限给用户和组。 admin中还会保存和显示对用户模型编辑的日志。
在admin的主页,你应该可以在“Auth”部分看到“Users”链接。 “Add user” 页面与标准admin页面不同点在于它要求你在编辑用户的其它字段之前先选择一个用户名和密码。
另请注意:如果你想使得一个用户能够使用Django的admin站点创建其它用户, 你需要给他添加用户和修改用户的权限(例如,"Add user” 和“Change user” 权限)。 如果一个账号具有添加用户的权限但是没有权限修改他们,该账号将不能添加用户。 为什么呢? 因为如果你具有添加用户的权限,你将可以添加超级用户,这些超级用户将可以修改其他用户。 所以Django同时要求添加权限和修改权限作为一种轻量的安全措施。
仔细考虑一下你是如何允许用户管理权限的。 如果你赋予了一个非超级用户编辑用户的能力,这和给他们超级用户的权限在最终效果上是一样的,因为他们将能够提升他们自己下面的用户的权限。
用户密码不会显示在admin上(也不会存储在数据库中),但是会显示password storage details。 这个信息的显示中包含一条指向修改密码表单的链接,允许管理员修改用户的密码。
2017年9月6日