使用 Django 的验证系统Link to this heading
本文档介绍了 Django 验证系统在默认配置下的使用方法。默认配置满足最常见的项目需求,可以处理相当多的任务,还有一个安全的密码和权限实现。对于验证需求与默认配置不同的项目,Django 支持对身份验证进行扩展和定制。
Django 验证同时提供身份验证和授权,通常称为身份验证系统,因为这些功能在某种程度上是耦合的。
User 对象Link to this heading
用户对象是认证系统的核心。它通常代表了与你的站点交互的人员,并用于允许诸如限制访问、注册用户配置文件、将内容与创建者关联等功能。Django 的认证框架中用户只有一个类,例如 “超级管理员”或“普通管理员”只是具有特殊属性集的用户对象,而不是用户对象的不同类。
默认用户的主要属性是:
请参阅完整的API文档 full API documentation 以获得完整的参考,下面的文档主要以任务为导向。
创建用户Link to this heading
创建用户最直接的方法是使用包含 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 管理后台,你也可以在 admin 管理后台交互式地创建用户:ref:create users interactively <auth-admin> 。
创建超级用户Link to this heading
通过命令行 createsuperuser 创建超级管理员:
$ python manage.py createsuperuser --username=joe --email=joe@example.com
你将会被提示输入密码,完成之后,超级管理员就被创建成功了。如果你没有填写参数 --username <createsuperuser --username> ` or :option:--email <createsuperuser --email>` ,也将会被提示输入这些值。
更改密码Link to this heading
Django 不会在用户模型里保存原始(明文)密码,而只会存储哈希值(请参阅文档 如何管理密码 documentation of how passwords are managed ) 。因此,请不要试图直接操作用户的密码,这就是创建用户需要辅助函数的原因。
更改一个用户的密码,你有几个选择:
manage.py changepassword *username* 提供了在命令行修改用户密码的方法。它会提示你输入两次新密码,如果操作成功,新密码就立刻生效。如果你没有提供参数 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 管理后台,你也可以在管理后台页面修改密码(请参阅 :ref:`authentication system's admin pages ` )。
Django 还提供了允许用户自行修改密码的 :ref:`views ` 和 :ref:`forms ` 。
修改密码将会注销用户的所有会话。查看详情请参阅 密码更改时会话失效 。
验证用户Link to this heading
- authenticate(request=None, **credentials)Link to this definition
使用
authenticate()来验证用户。它使用username和password作为参数来验证,对每个身份验证后端( authentication backend ` )进行检查。如果后端验证有效,则返回一个 :class:`~django.contrib.auth.models.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 credentialsrequest是可选的HttpRequest,它在身份验证后端上的authenticate()方法来传递。
Web 请求的认证Link to this heading
Django 使用 sessions 和中间件将身份验证系统挂接到请求对象中。
它们在每次请求中都会提供 request.user 属性。如果当前没有用户登录,这个属性将会被设置为 AnonymousUser ,否则将会被设置为 User 实例。
你可以使用 is_authenticated 区分两者,例如:
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
用户如何登陆Link to this heading
如果有一个已验证的用户想附加到当前会话(session)中,将通过 login() 函数完成。
- login(request, user, backend=None)Link to this definition
要在视图中让用户登录,使用
login()。它需要HttpRequest对象和User对象。通过 Django 的 session 框架,login()会在 session 中保存用户的ID。注意,在匿名会话期间设置的任何数据都会在用户登录后保留在会话中。
这个例子展示了如何使用
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. ...
选择验证后端Link to this heading
当用户登录时,用户 ID 和用于身份验证的后端会被保存在用户会话中。允许相同的 authentication backend 在未来的请求中获取用户详情。选择要在会话中保存的验证后端如下:
使用提供了的可选
backend参数值。使用
user.backend的值。允许配对authenticate()和login():当返回用户对象时authenticate()设置user.backend属性。使用
AUTHENTICATION_BACKENDS存在的backend。否则,抛出一个异常。
在1和2中,backend 参数和 user.backend 属性应该是完整的导入路径(像 AUTHENTICATION_BACKENDS 里的路径一样),而不是真实的后端类。
用户如何登出Link to this heading
- logout(request)Link to this definition
如果已经通过
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()之后执行此操作。
限制对未登录用户的访问Link to this heading
原始方式Link to this heading
限制访问页面最原始的办法就是检查 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 装饰器Link to this heading
- login_required(redirect_field_name='next', login_url=None)Link to this definition
作为快捷方式,你可以使用
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也接受视图方法名和 named URL patterns 。这样你可以在 URLconf 里自由地重新映射你的登录视图,而不需更新配置文件。
Note
login_required 装饰器不会检查用户的 is_active 标识状态,但默认的 AUTHENTICATION_BACKENDS 会拒绝非正常用户。
See also
如果你打算编写自定义的 Django 管理模块视图(或需要与内置视图使用同样的权限检查),你将会发现 django.contrib.admin.views.decorators.staff_member_required() 装饰器是 login_required() 的一个有用的替代方法。
LoginRequired MixinLink to this heading
使用基于类的视图时,可以使用 LoginRequiredMixin 实现和 login_required 相同的行为。这个 Mixin 应该在继承列表中最左侧的位置。
- class LoginRequiredMixinLink to this definition
如果一个视图使用 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'
Note
同 login_required 装饰器一样,Mixin 不会检查用户的 is_active 标识状态,但默认的 AUTHENTICATION_BACKENDS 会拒绝非正常用户。
限制对通过测试的登录用户的访问Link to this heading
根据某些权限或者其他测试来限制访问,你基本上可以执行和上一节所述同样的操作。
可以在视图里直接对 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')Link to this definition
作为快捷方式,你可以方便的调用
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()接受一个必要的参数:一个带有:class:~django.contrib.auth.models.User 对象的调用,如果允许用户访问这个页面,则返回True。注意,user_passes_test()不会自动检查用户是否匿名。user_passes_test()可以传递两个可选参数:login_url允许你指定用户没有通过测试时跳转的地址。它可能是一个登录页面,如果你没指定,默认是
settings.LOGIN_URL。redirect_field_name与
login_required()相同。如果你想把没通过检查的用户重定向到没有 "next page" 的非登录页面时,把它设置为None,这样它会在 URL 中移除。
例如:
@user_passes_test(email_check, login_url='/login/') def my_view(request): ...
- class UserPassesTestMixinLink to this definition
使用基于类的视图时,可以使用
UserPassesTestMixin执行此操作。- test_func()Link to this definition
你必须覆盖类方法
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()Link to this definition
你也可以覆盖
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 装饰器Link to this heading
- permission_required(perm, login_url=None, raise_exception=False)Link to this definition
检查用户是否拥有特定的权限是一个相对常见的任务。出于这个原因,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.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默认是:setting:settings.LOGIN_URL <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.add_choice', raise_exception=True) def my_view(request): ...当
LoginView的redirect_authenticated_user=True并且已登录用户没有所有必须的权限时,这避免了重定向循环。
PermissionRequiredMixin MixinLink to this heading
在 class-based views 中应用权限检查,你可以使用 PermissionRequiredMixin :
- class PermissionRequiredMixinLink to this definition
和
permission_required装饰器一样,Mixin 检查用户访问的视图是否拥有全部的权限。你应该使用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()Link to this definition
返回 Mixin 使用的可迭代权限的名称。默认为
permission_required属性,如果需要可以转化为元组。
- has_permission()Link to this definition
返回布尔值,表示当前用户是否拥有权限执行装饰器视图。默认情况下,这将返回调用
has_perms()的结果,其中包括返回get_permission_required()的权限列表。
验证视图Link to this heading
Django 提供许多可以用来处理登录、注销和密码管理的视图。这些利用了 stock auth forms ,但你也可以使用自己的表单。
Django 没有为验证视图提供默认模板。你可以为你打算使用的视图创建自己的模板。每个视图都记录了模板上下文,详情查看 所有的验证视图 。
使用视图Link to this heading
在项目中可以使用不同方法来实现这些视图。最简单的方法就是在 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 模式的使用详情参考 the URL documentation 。
如果你想更好的控制 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'),
),
]
所有视图都是基于类的,这就允许你通过子类去方便地自定义它们。
所有的验证视图Link to this heading
这是一个 django.contrib.auth 提供的所有视图列表。有关实现细节可参考 使用视图 。
- class LoginViewLink to this definition
URL name:
login有关使用命名 URL 模式的细节可参考 the URL documentation 。
属性:
template_name:用户登录的视图所使用的模板名称。默认指向registration/login.html。redirect_field_name:GET字段包含的登录后跳转 URL 的参数名称。默认是next。authentication_form:用于验证的调用(通常是一个表单类)。默认是AuthenticationForm。extra_context:上下文数据字典,通过模板添加到默认上下文数据中。redirect_authenticated_user:布尔值,用来控制已验证的用户访问登录页面是否被重定向,就像他们刚刚成功登录一样。默认是False。Warning
如果你启用了
redirect_authenticated_user,其他网站通过重定向请求你的网站的图片文件的方式来确定他们的访客是否是你网站的已验证用户。为了避免这个 "social media fingerprinting" 信息泄露,请将所有图片和 favicon 都托管在单独的域名中。启用
redirect_authenticated_user也会在使用permission_required()装饰器的时候,导致重定向循环,除非raise_exception参数被使用。success_url_allowed_hosts:除了request.get_host()之外的主机集合,登录后能安全地重定向。默认是空集。
LoginView能做什么:如果通过
GET调用,它将显示 POST 到同一 URL 地址的登录表单。稍后会详细介绍。如果用户提交的数据通过
POST调用,那它将试着让用户登录。如果登录成功,那么视图将重定向到next指定的 URL 。如果没有提供next,它将重定向到settings.LOGIN_REDIRECT_URL(默认/accounts/profile/)。如果登录没有成功,它将重新显示登录表单。
你需要提供登录模板,默认调用
registration/login.html。这个模板传递四个模板上下文变量:form:一个代表AuthenticationForm的Form对象。next:登录成功后跳转的网址。这可能包含查询字段。site:根据SITE_ID设置的当前站点。如果你还没有安装站点框架,会将其设置为RequestSite实例,该实例从当前HttpRequest中派生出站点名和域名。site_name:site.name的别名。如果你还没有按照站点框架,它将设置为request.META['SERVER_NAME']的值。更多关于站点信息,请参考 The "sites" framework 。
如果你不愿意调用模板
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')),你也可以使用
redirect_field_name指定GET字段的名称,这个字段包含登陆后跳转的 URL 地址。默认情况下,这个字段为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 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()方法(这个方法只会在表单成功验证后调用)。
- class LogoutViewLink to this definition
注销用户
URL name:
logout属性:
next_page:注销后将要跳转的 URL 。默认是settings.LOGOUT_REDIRECT_URL。template_name:用户注销后显示的模板地址。默认是registration/logged_out.html。redirect_field_name:注销后包含重定向 URL 的GET字段名称。默认是next。如果传递给定的GET参数,将会覆盖next_pageURL。extra_context:上下文数据字典,通过模板添加到默认上下文数据中。success_url_allowed_hosts:除了request.get_host()之外的主机集合,在注销后可以安全地重定向。默认是空集。
Template context:
title:字符串 "已注销",已本地化。site:根据SITE_ID设置的当前站点。如果你还没有安装站点框架,会将其设置为RequestSite实例,该实例从当前HttpRequest中派生出站点名和域名。site_name:site.name的别名。如果你还没有按照站点框架,它将设置为request.META['SERVER_NAME']的值。更多关于站点信息,请参考 The "sites" framework 。
- logout_then_login(request, login_url=None)Link to this definition
用户注销,然后重定向到登录页面。
URL name: 没有提供默认的 URL
可选参数:
login_url:要重定向到登录页面的 URL 。如果没有提供,默认是settings.LOGIN_URL。
- class PasswordChangeViewLink to this definition
URL name:
password_change允许用户修改密码。
属性:
template_name:用于显示密码修改表单的模板全称。如果没提供则默认registration/password_change_form.html。success_url:密码修改成功后跳转的 URL 。默认是'password_change_done'。form_class:一个自定义修改密码的表单,此表单必须接收user关键字参数。表单负责实际修改用户密码。默认是PasswordChangeForm。extra_context:上下文数据字典,通过模板添加到默认上下文数据中。
Template context:
form:密码修改表单(参考上面的form_class)
- class PasswordChangeDoneViewLink to this definition
URL name:
password_change_done用户修改密码之后显示的页面。
属性:
template_name:所使用模板的全称。如果没有提供,则默认registration/password_change_done.html。extra_context:上下文数据字典,通过模板添加到默认上下文数据中。
- class PasswordResetViewLink to this definition
URL name:
password_reset允许用户通过生成的一次性链接来重置密码,并把一次性链接发到用户注册邮箱中。
如果邮箱地址并不存在,视图不会发送邮件,但用户也不会受到任何错误信息。这是为了防止信息泄露给潜在的攻击者。如果你想提供错误信息,你可以成为继承
PasswordResetForm,并使用form_class属性。Note
注意,发送邮件需要花费额外时间,因此,由于对现有电子邮件地址的重置请求的持续时间与对不存在的电子邮件地址的重置请求的持续时间不同,你可能容易受到电子邮件地址枚举定时攻击。为了降低开销,你可以使用第三方插件来允许异步发送邮件,例如 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 使用DEFAULT_FROM_EMAIL。extra_context:上下文数据字典,通过模板添加到默认上下文数据中。html_email_template_name:用来生成带有密码重置链接的text/html多用途电子邮件。默认情况下,HTML 单子邮件不会被发送。extra_email_context: 在邮件模板提供上下文数据字典。它被用来覆盖下面列出的默认模板上下文值,比如domain。
Template context:
form:重置用户密码的表单(可参考上面的form_class)。
电子邮件模板上下文:
email:user.email的别名。user:根据电子邮件表单字段指定的当前用户。只有活动用户才可以重置密码(User.is_active 为 True)。site_name:site.name的别名。如果你还没有按照站点框架,它将设置为request.META['SERVER_NAME']的值。更多关于站点信息,请参考 The "sites" framework 。domain:site.domain的别名。如果你还没有安装网站框架,它会被设置为request.get_host()的值。protocol:http 或 httpsuid:使用 Base64 编码过的用户主键。token:检测重置密码链接是否有效的 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 PasswordResetDoneViewLink to this definition
URL name:
password_reset_done发送重置密码邮件后显示的页面。如果
PasswordResetView没有明确设置success_url,那么默认将该视图调用。Note
如果提供的电子邮件地址在系统内并不存在,那么用户可能是非活动用户,或者密码不可被更改。用户仍然会重定向到这个视图,但不会发送邮件。
属性:
template_name:被使用模板的全称。如果没有提供,则默认是registration/password_reset_done.htmlextra_context:上下文数据字典,通过模板添加到默认上下文数据中。
- class PasswordResetConfirmViewLink to this definition
URL name:
password_reset_confirm提供输入新密码的表单。
URL 的关键参数
uidb64:被Base64编码过的用户 id。token:检查密码是否有效的 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: Token 参数为密码重置链接的组成部分。默认'set-password'。Changed in Django 3.0
已添加
reset_url_token类属性。
Template context:
form:用来设置用户新密码的表单(查看上面的form_class)。validlink:布尔值,如果链接(uidb64和token的组合)有效且合法,则返回 True 。
- class PasswordResetCompleteViewLink to this definition
URL name:
password_reset_complete当密码已经被修改成功后通知用户的视图。
属性:
template_name:显示视图的模板全称。默认registration/password_reset_complete.html。extra_context:上下文数据字典,通过模板添加到默认上下文数据中。
辅助函数Link to this heading
- redirect_to_login(next, login_url=None, redirect_field_name='next')Link to this definition
重定向到登录页面,登陆成功后跳转到其他 URL 。
必要参数
next:成功登陆后跳转的 URL。
可选参数:
login_url:要重定向到登录页面的 URL 。如果没有提供,默认是settings.LOGIN_URL。redirect_field_name:注销后跳转的 URL 所包含的GET字段名称。如果已传递给定的GET参数,则覆盖next。
内置表单Link to this heading
如果你不想使用内置视图,但希望不必为此功能编写表单,验证系统提供很多在 django.contrib.auth.forms 中的内置表单。
Note
内置验证表单对用户正在使用的的用户模型做了某些假设。如果你正在使用 custom user model ` ,它可能需要为验证系统定义你自己的表单。如需了解更多信息,参考文档 :ref:`using the built-in authentication forms with custom user models 。
- class AdminPasswordChangeFormLink to this definition
在管理界面修改用户密码所使用的表单。
将
user作为第一个参数。
- class AuthenticationFormLink to this definition
用户登录的表单。
将
request作为第一个参数,该参数存储在表单实例上,供子类使用。- confirm_login_allowed(user)Link to this definition
默认情况下,
AuthenticationForm拒绝is_active标识为False的用户。你可以通过自定义策略来覆盖这个行为来决定哪个用户可以登录。通过``AuthenticationForm`` 子类的自定义表单来执行这个操作,并覆盖confirm_login_allowed()方法。如果给定的用户无法登录,这个方法应该引发ValidationError错误。举例,允许所有用户登录而不管 "active" 状态:
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 PasswordChangeFormLink to this definition
允许用户修改密码的表单:
- class PasswordResetFormLink to this definition
生成和邮件发送一次性重置密码链接的表单。
- send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)Link to this definition
使用参数发送
EmailMultiAlternatives。可以重写自定义邮件发送给用户的方式。- 参数:
subject_template_name -- 主题模板
email_template_name -- 邮件主体模板
context -- 上下文传递至
subject_template,email_template, 和html_email_template(如果它非空)。from_email -- 发送方的邮箱地址。
to_email -- 接收方的邮箱地址。
html_email_template_name -- HTML 正文模板;默认是
None,在这种情况下发送纯文本邮件。
默认情况下,
save()使用PasswordResetView传递给其电子邮件上下文的相同变量填充上下文。
- class SetPasswordFormLink to this definition
让用户不输入旧密码就能改变它们密码的表单。
- class UserChangeFormLink to this definition
在管理界面修改用户信息和权限的表单。
- class UserCreationFormLink to this definition
建立新用户的
ModelForm。它有三个字段:
username(来自用户模型),password1,和password2。它检查password1和password2是否匹配,使用validate_password()验证密码,并且使用set_password()来设置用户密码。
模板内验证数据Link to this heading
当你使用 RequestContext 时,当前已登录用户和他们的权限在 :doc:`template context ` 中是可用的。
技术细节
从技术上讲,如果你使用 RequestContext ,这些变量只在模板上下文中可用,并且已启用 'django.contrib.auth.context_processors.auth' 处理机。它默认产生配置文件。了解更多,可以查看 RequestContext docs 。
用户Link to this heading
当渲染模板 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 ,那么这个模板上下文变量将不可用。
权限Link to this heading
当前登录用户的权限保存在模板变量 {{ perms }} 中。这是 django.contrib.auth.context_processors.PermWrapper 的一个实例,它是一个对模板友好的权限代理。
将 {{ perms }} 的单属性查找作为布尔值为 User.has_module_perms() 的代理。比如,检测登录用户是否拥有一些权限:
{% 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 %}
在管理界面中管理用户Link to this heading
当安装了 django.contrib.admin 和 django.contrib.auth,管理后台提供了方便的方法来查看和管理用户、组和权限。用户可以增加和删除任何 Django 模型。可以创建组,也可以为用户和组分配权限。用户操作模型的日志也会在管理后台中保存和显示。
创建用户Link to this heading
你可以在管理后台主页的 “认证和权限” 部分看到 “用户” 链接。“增加用户”的管理界面和其他标准的管理后台不同的是:你需要先输入一个新用户名和新密码,然后才能编辑新用户的剩余字段。
注意:如果你希望某个用户账号可以在 Django 管理后台创建用户,你将需要给用户“创建”和“修改”权限。如果账号只有“创建”权限但没有“修改”权限,那么这个账号将不能增加用户。为什么?因为你有权限添加用户,那么你就拥有添加超级管理员的权利,而超级管理员就可以修改其他用户。因此,Django 需要添加和修改权限作为安全措施。
要考虑如何允许用户去管理权限。如果你允许普通管理员编辑用户,这和给他们超级管理员权限一样。因为他们有权利提升用户权限,包括他们自己。
更改密码Link to this heading
用户密码不显示在管理界面中(也不在数据库中保存),但会显示 password storage details 。这个信息中包含一个指向密码修改表单的链接,该表单允许管理员修改用户密码。