django 1.8 官方文档翻译:13-1-2 使用Django认证系统

使用Django认证系统

这篇文档解释默认配置下Django认证系统的使用。这些配置已经逐步能够知足大部分常见项目对的须要,能够处理范围很是普遍的任务,且具备一套细致的密码和权限实现。对于须要与默认配置不一样需求的项目,Django支持_扩展和自定义_认证。html

Django的认证同时提供认证和受权,并一般统一称为认证系统,由于这些功能某些地方是耦合的。python

User对象

User对象是认证系统的核心。它们一般表示与你的站点进行交互的用户,并用于启用限制访问、注册用户信息和关联内容给建立者等。在Django的认证框架中只存在一种类型的用户,所以诸如'superusers'或管理员'staff'用户只是具备特殊属性集的user对象,而不是不一样类型的user对象。数据库

默认user的基本属性有:django

完整的参考请参阅full API documentation,该文档更偏重特定的任务。app

建立users

建立users最直接的方法是使用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,你也能够_间接地建立users_.

建立superusers

使用createsuperuser命令建立superusers:

$ python manage.py createsuperuser --username=joe --email=joe@example.com

将会提示你输入一个密码。在你输入一个密码后,该user将会当即建立。若是不带--username--email选项,将会提示你输入这些值。

修改密码

Django不会在user模型上存储原始的(明文)密码,而只是一个哈希(完整的细节参见_文档:密码是如何管理的_)。由于这个缘由,不要尝试直接操做user的password属性。这也是为何建立一个user时要使用辅助函数。

若要修改一个用户的密码,你有几种选择:

manage.py changepassword *username*提供一种从命令行修改User密码的方法。它提示你修改一个给定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,你还能够在_认证系统的admin页面_修改user的密码。

Django还提供_views__forms_用于容许user修改他们本身密码。

New in Django 1.7\.

若是启用了SessionAuthenticationMiddleware,修改user的密码将会登出他们全部的会话。 详细信息请参阅_密码修改后会话失效_

认证Users

authenticate(_**credentials_)[source]

认证一个给定用户名和密码,请使用authenticate()。它以关键字参数形式接收凭证,对于默认的配置它是usernamepassword,若是密码对于给定的用户名有效它将返回一个User对象。若是密码无效,authenticate()返回None。例子:

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # the password verified for the user
    if user.is_active:
        print()
    else:
        print()
else:
    # the authentication system was unable to verify the username and password
    print()

这是认证一系列凭证的低级的方法;例如,它被RemoteUserMiddleware使用。除非你正在编写你本身的认证系统,你可能不会使用到它。固然若是你在寻找一种登陆user的方法,请参见login_required()装饰器。

权限和受权

Django从开始就带有一个简单的权限系统。它提供一种分配权限给特定的用户和用户组的方法。

它被Django的admin站点使用,但欢迎你在你本身的代码中使用。

Django admin 站点使用以下的权限:

  • 查看"add"表单并添加一个只限具备该类型对象的“add”权限的用户对象。

  • 查看修改列表、查看“change”表单以及修改一个只限具备该类型对象的“change”权限的用户对象。

  • 删除一个只限具备该类型对象的“delete”权限的用户对象。

权限不但能够根据每一个对象的类型,并且能够根据特定的对象实例设置。经过使用ModelAdmin类提供的has_add_permission()has_change_permission()has_delete_permission()方法,能够针对相同类型的不一样对象实例自定义权限。

User对象具备两个多对多的字段:groupsuser_permissionsUser对象能够用和其它_Django 模型_同样的方式访问它们相关的对象:

myuser.groups = [group_list]
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions = [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.authINSTALLED_APPS中以后,当你第一次运行migrate时,将会为以前安装的模型建立默认的权限,包括与其同时正在安装的新的模型。以后,每当你运行manage.py migrate时,它都将为新的模型建立默认的权限。

假设你有个应用的app_labelfoo和一个名为Bar的模型,要测试基本的权限,你应该使用:

  • add: user.has_perm('foo.add_bar')

  • change: user.has_perm('foo.change_bar')

  • delete: 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 Group, 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在第一次须要访问User对象来检查权限时会缓存它们的权限。这对于请求-响应循环仍是比较好的,由于在权限添加进来以后并不会当即检查(例如在admin中)。若是你正在添加权限并须要当即检查它们,例如在一个测试或视图中,最简单的解决办法是从数据库中从新获取User。 例如:

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
    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 对象到认证系统中。

它们在每一个请求上提供一个request.user属性,表示当前的用户。若是当前的用户没有登入,该属性将设置成AnonymousUser的一个实例,不然它将是User的实例。

你能够经过is_authenticated()区分它们,像这样:

if request.user.is_authenticated():
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

如何登入一个用户

若是你有一个认证了的用户,你想把它附带到当前的会话中 - 这能够经过login()函数完成。

login()[source]

从视图中登入一个用户,请使用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:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
            ...
    else:
        # Return an 'invalid login' error message.
        ...

先调用authenticate()

当你是手工登入一个用户时,你_必须_在调用login()以前经过authenticate()成功地认证该用户。authenticate()User上设置一个属性标识哪一种认证后台成功认证了该用户(细节参见_后台的文档_),且该信息在后面登陆的过程当中是须要的。若是你视图登入一个直接从数据库中取出的用户,将会抛出一个错误。

如何登出一个用户

logout()[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=REDIRECT_FIELD_NAME_, _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/

  • 若是用户已经登入,则正常执行视图。视图的代码能够安全地假设用户已经登入。

默认状况下,在成功认证后用户应该被重定向的路径存储在查询字符串的一个叫作)带有一个可选的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同时还接收视图函数名和_命名的URL模式_。这容许你自由地从新映射你的URLconf中的登陆视图而不用更新设置。

login_required装饰器不检查user的is_active标志位。

给已验证登陆的用户添加访问限制

基于特定的权限和其余方式来限制访问,你最好按照前面所叙述的那样操作。

简单的方法就是在视图中直接运行你对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(_func_, _login_url=None_, _redirect_field_name=REDIRECT_FIELD_NAME_])[[source]

你能够用方便的 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

让你指定那些没有经过检查的用户要重定向至哪里。若不指定其值,它多是默认的 settings.LOGIN_URL

redirect_field_name

login_required()的参数相同。把它设置为 None 来把它从 URL 中移除,当你想把通不过检查的用户重定向到没有next page 的非登陆页面时。

例如:

@user_passes_test(email_check, login_url='/login/')
def my_view(request):
    ...

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) 视图_而不是重定向到登陆页面。

Changed in Django 1.7:

permission_required()装饰器既能够接收一个权限序列也能够接收一个单个的权限。

对普通的视图使用权限

若要对一个_基于类的普通视图_使用权限,能够在该类上装饰View.dispatch方法。详细细节参见_Decorating the class_。 另一个方法是_编写一个封装as_view()的mixin_

密码更改后的会话失效

New in Django 1.7\.

警告

这种保护只在MIDDLEWARE_CLASSESSessionAuthenticationMiddleware开启的状况下应用。若是settings.py由Django ≥ 1.7\. 的startproject生成,它会被包含进来。

在Django 2.0中,会话验证会变成强制性的, 不管是否开启了SessionAuthenticationMiddleware 。 若是你拥有一个1.7以前的项目,或者使用不包含SessionAuthenticationMiddleware的模板生成的项目,考虑在阅读下面的升级说明以后开启它。

若是你的AUTH_USER_MODEL继承自AbstractBaseUser,或者实现了它本身的get_session_auth_hash()方法,验证后的会话会包含这个函数返回的哈希值。在AbstractBaseUser的状况中,这是密码字段的HMAC。若是开启了SessionAuthenticationMiddleware ,Django会验证每一个请求带有的哈希值是否匹配服务端计算出来的哈希值。这容许用户经过修改密码来登出全部的会话。

Django中包含的默认的密码修改视图,以及django.contrib.auth中的 django.contrib.auth.views.password_change()user_change_password视图 ,会使用新的密码哈希值升级会话,以便用户在修改密码是不会登出。若是你拥有自定义的密码修改视图,而且但愿具备类似的行为,使用这个函数:

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:
        ...

若是你在升级一个现存的站点,而且但愿开启这一中间件,而不但愿你的全部用户以后从新登陆,你能够首先升级到DJango1.7而且运行它一段时间,以便全部会话在用户登陆时天然被建立,它们包含上面描述的会话哈希。一旦你使用SessionAuthenticationMiddleware开始运行你的站点,任何没有登陆而且会话使用验证哈希值升级过的用户的现有会话都会失效,而且须要从新登陆。

注意

虽然get_session_auth_hash()给予SECRET_KEY,使用新的私钥升级你的站点会使全部现有会话失效。

认证的视图

Django提供一些视图,你能够用来处理登陆、登出和密码管理。它们使用_stock auth 表单_,但你也能够传递你本身的表单。

Django没有为认证视图提供默认的模板。你应该为你想要使用的视图建立本身的模板。模板的上下文定义在每一个视图中,参见_全部的认证视图_.

使用视图

有几种不一样的方法在你的项目中使用这些视图。最简单的方法是包含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模式的细节请参见_URL文档_

若是你想更多地控制你的URL,你能够在你的URLconf中引用一个特定的视图:

urlpatterns = [
    url('^change-password/', 'django.contrib.auth.views.password_change')
]

这些视图具备可选的参数,你能够用来改变视图的行为。例如,若是你想修改一个视图使用的模板名称,你能够提供template_name参数。实现它的一种方法是在URLconf中提供一个关键字参数,它们将被传递到视图中。例如:

urlpatterns = [
    url(
        '^change-password/',
        'django.contrib.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_, _redirect_field_name_, _authentication_form_, _current_app_, _extra_context_])[[source]

URL 名称:login

关于使用命名URL模式的细节参见_URL 文档_

可选的参数:

  • template_name: 用于用户登陆视图的模板名。默认为registration/login.html

  • redirect_field_name: GET字段的名称,包含登录后重定向URL。默认为next

  • authentication_form: 用于认证的可调用对象(一般只是一个表单类)。默认为AuthenticationForm

  • current_app: 指示包含当前视图的是哪一个应用。更多信息参见命名URL的解析策略

  • extra_context: 一个上下文数据的字典,将被添加到传递给模板的默认上下文数据中。

下面是django.contrib.auth.views.login所作的事情:

  • 若是经过 GET调用,它显示一个POST给相同URL的登陆表单。后面有更多这方面的信息。

  • 若是经过POST调用并带有用户提交的凭证,它会尝试登入该用户。若是登入成功,该视图重定向到next中指定的URL。若是next没有提供,它重定向到settings.LOGIN_REDIRECT_URL(默认为/accounts/profile/)。若是登入不成功,则从新显示登陆表单。

你须要提供html模板给login,默认调用registration/login.html。模板会获得4个模板上下文变量:

  • form: 一个表示AuthenticationFormForm对象。

  • next: 登入成功以后重定向的URL。它还可能包含一个查询字符串。

  • site: 若是你没有安装site框架,这将被设置成RequestSite的一个实例,它从当前的HttpRequest得到site名称和域名。

  • site_name: site.name的别名。若是你没有安装site框架,这将被设置成request.META['SERVER_NAME']的值。关于site 的更多信息,参见_“sites” 框架_

若是你不喜欢调用registration/login.html,你能够经过额外的参数传递template_name参数给你URLconf中的视图。例如,下面URLconf中的行将使用myapp/login.html

url(r'^accounts/login/$', auth_views.login, {'template_name': 'myapp/login.html'}),

经过传递redirect_field_name给视图,你还能够指定GET字段的值,它包含登入成功后的重定向的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 %}

<form method="post" action="{% url 'django.contrib.auth.views.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>

{% endblock %}

若是你自定义认证(参见_Customizing Authentication_),你能够经过authentication_form参数传递一个自定义的认证表单给登陆视图。该表单必须在它的__init__方法中接收一个request关键字参数,并提供一个get_user方法,此方法返回认证过的用户对象(这个方法永远只在表单验证成功后调用)。

logout(_request_, _next_page_, _template_name_, _redirect_field_name_, _current_app_, _extra_context_])[[source]

登出一个用户。

URL名称:logout

可选的参数:

  • next_page: 登出以后要重定向的URL。

  • template_name: 用户登出以后,要展现的模板的完整名称。若是不提供任何参数,默认为registration/logged_out.html

  • redirect_field_name: 包含登出以后所重定向的URL的GET字段的名称。默认为 next。若是提供了GET参数,会覆盖next_page URL。

  • current_app: 一个提示,代表哪一个应用含有了当前视图。 详见 命名空间下的URL解析策略

  • extra_context: 一个上下文数据的字典,会被添加到向模板传递的默认的上下文数据中。

模板上下文:

  • title: 本地化的字符串“登出”。

  • site: 根据SITE_ID 设置的当前站点。若是你并无安装站点框架,会设置为 RequestSite的示例,它从当前HttpRequest来获取站点名称和域名。

  • site_name: site.name的别名。若是没有安装站点框架,会设置为request.META['SERVER_NAME']。站点的更多信息请见_“站点”框架_

  • current_app: 一个提示,代表哪一个应用含有了当前视图。 详见 命名空间下的URL解析策略

  • extra_context: 一个上下文数据的字典,会被添加到向模板传递的默认的上下文数据中。

logout_then_login(_request_, _login_url_, _current_app_, _extra_context_])[[source]

登出一个用户,而后重定向到登陆页面。

URL 名称: 没有提供默认的URL

可选的参数:

  • login_url: 登陆页面要重定向的URL。若是没有提供,默认为settings.LOGIN_URL

  • current_app: 一个提示,代表哪一个应用含有了当前视图。详见 命名空间下的URL解析策略

  • extra_context: 一个上下文数据的字典,会被添加到向模板传递的默认的上下文数据中。

password_change(_request_, _template_name_, _post_change_redirect_, _password_change_form_, _current_app_, _extra_context_])[[source]

容许一个用户修改他的密码。

URL 名称:password_change

可选的参数:

  • template_name: 用来显示修改密码表单的template的全名。若是没有提供,默认为registration/password_change_form.html

  • post_change_redirect: 密码修改为功后重定向的URL。

  • password_change_form: 一个自定义的“修改密码”表单,必须接受user 关键词参数。表单用于实际修改用户密码。默认为 PasswordChangeForm

  • current_app: 一个提示,暗示哪一个应用包含当前的视图。详见 命名空间下的URL解析策略

  • extra_context: 上下文数据的字典,会添加到传递给模板的默认的上下文数据中。

模板上下文:

  • form: 密码修改表单(请见上面的password_change_form)。

password_change_done(_request_, _template_name_, _current_app_, _extra_context_])[[source]

这个页面在用户修改密码以后显示。

URL 名称:password_change_done

可选参数:

  • template_name: 所使用模板的完整名称。若是没有提供,默认为registration/password_change_done.html

  • current_app: 一个提示,暗示哪一个应用包含当前的视图。 详见 命名空间下的URL解析策略

  • extra_context: 上下文数据的字典,会添加到传递给模板的默认的上下文数据中。

password_reset(_request_, _is_admin_site_, _template_name_, _email_template_name_, _password_reset_form_, _token_generator_, _post_reset_redirect_, _from_email_, _current_app_, _extra_context_, _html_email_template_name_])[[source]

容许用户经过生成一次性的链接并发送到用户注册的邮箱地址中来重置密码。

若是提供的邮箱地址不在系统中存在,这个视图不会发送任何邮件,可是用户也不会收到任何错误信息。这会阻止数据泄露给潜在的攻击者。若是你打算在这种状况提供错误信息,你能够继承PasswordResetForm,并使用password_reset_form 参数。

用无效密码标记的用户(参见set_unusable_password())不容许请求重置密码,为了防止使用相似于LDAP的外部验证资源时的滥用。注意它们不会收到任何错误信息,由于这会暴露它们的帐户,也不会发送任何邮件。

URL 名称:password_reset

可选参数:

  • template_name: The full name of a template to use for

    displaying the password reset form. Defaults to
    `registration/password_reset_form.html` if not supplied.
  • email_template_name: The full name of a template to use for

    generating the email with the reset password link. Defaults to
    `registration/password_reset_email.html` if not supplied.
  • subject_template_name: The full name of a template to use for

    the subject of the email with the reset password link. Defaults
    to `registration/password_reset_subject.txt` if not supplied.
  • password_reset_form: Form that will be used to get the email of

    the user to reset the password for. Defaults to
    [{{s.379}}](#django.contrib.auth.forms.PasswordResetForm ).
  • token_generator: Instance of the class to check the one time link.

    This will default to `default_token_generator`, it’s an instance of
    `django.contrib.auth.tokens.PasswordResetTokenGenerator`.
  • post_reset_redirect: The URL to redirect to after a successful

    password reset request.
  • from_email: A valid email address. By default Django uses

    the [DEFAULT_FROM_EMAIL](../../ref/settings.html#std:setting-DEFAULT_FROM_EMAIL).
  • current_app: A hint indicating which application contains the current

    view. See the [{{s.385}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
  • extra_context: A dictionary of context data that will be added to the

    default context data passed to the template.
  • html_email_template_name: The full name of a template to use

    for generating a `text/html` multipart email with the password reset
    link. By default, HTML email is not sent.

New in Django 1.7:

添加了html_email_template_name

Deprecated since version 1.8: is_admin_site参数已被废弃,将在Django2.0中被移除。

模板上下文:

  • form: The form (see password_reset_form above) for resetting

    the user’s password.

Email模板上下文:

  • email: An alias for user.email

  • user: The current User,

    according to the `email` form field. Only active users are able to
    reset their passwords (`User.is_active is True`).
  • site_name: An alias for site.name. If you don’t have the site

    framework installed, this will be set to the value of
    [request.META['SERVER_NAME']](../../ref/request-response.html#django.http.HttpRequest.META ).
    For more on sites, see [_The “sites” framework_](../../ref/contrib/sites.html).
  • domain: An alias for site.domain. If you don’t have the site

    framework installed, this will be set to the value of
    `request.get_host()`.
  • protocol: http or https

  • uid: The user’s primary key encoded in base 64.

  • token: Token to check that the reset link is valid.

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_, _current_app_, _extra_context_])[[source]

这个页面在向用户发送重置密码的邮件后展现。若是password_reset()视图没有显式设置 post_reset_redirectURL,默认会调用这个视图。

URL名称:password_reset_done

注意

若是提供的email地址在系统中不存在,用户未激活,或者密码不可用,用户仍然会重定向到这个视图,可是不会发送邮件。

可选参数:

  • template_name: The full name of a template to use.

    Defaults to `registration/password_reset_done.html` if not
    supplied.
  • current_app: A hint indicating which application contains the current

    view. See the [{{s.393}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
  • extra_context: A dictionary of context data that will be added to the

    default context data passed to the template.

password_reset_confirm(_request_, _uidb64_, _token_, _template_name_, _token_generator_, _set_password_form_, _post_reset_redirect_, _current_app_, _extra_context_])[[source]

为输入新密码展现表单。

URL名称:password_reset_confirm

可选参数:

  • uidb64: The user’s id encoded in base 64\. Defaults to None.

  • token: Token to check that the password is valid. Defaults to

    `None`.
  • template_name: The full name of a template to display the confirm

    password view. Default value is `registration/password_reset_confirm.html`.
  • token_generator: Instance of the class to check the password. This

    will default to `default_token_generator`, it’s an instance of
    `django.contrib.auth.tokens.PasswordResetTokenGenerator`.
  • set_password_form: Form that will be used to set the password.

    Defaults to [{{s.395}}](#django.contrib.auth.forms.SetPasswordForm )
  • post_reset_redirect: URL to redirect after the password reset

    done. Defaults to `None`.
  • current_app: A hint indicating which application contains the current

    view. See the [{{s.400}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
  • extra_context: A dictionary of context data that will be added to the

    default context data passed to the template.

Template context:

  • form: The form (see set_password_form above) for setting the

    new user’s password.
  • validlink: Boolean, True if the link (combination of uidb64 and

    `token`) is valid or unused yet.

password_reset_complete(_request_, _template_name_, _current_app_, _extra_context_])[[source]

展现一个视图,它通知用户密码修改为功。

URL名称:password_reset_complete

可选参数:

  • template_name: The full name of a template to display the view.

    Defaults to `registration/password_reset_complete.html`.
  • current_app: A hint indicating which application contains the current

    view. See the [{{s.403}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
  • extra_context: A dictionary of context data that will be added to the

    default context data passed to the template.

辅助函数

redirect_to_login(_next_, _login_url_, _redirect_field_name_])[[source]

重定向到登陆页面,而后在登入成功后回到另外一个URL。

必需的参数:

  • next: The URL to redirect to after a successful login.

可选的参数:

  • login_url: The URL of the login page to redirect to.

    Defaults to [{{s.411}}](../../ref/settings.html#std:setting-LOGIN_URL) if not supplied.
  • redirect_field_name: The name of a GET field containing the

    URL to redirect to after log out. Overrides `next` if the given
    `GET` parameter is passed.

内建的表单

若是你不想用内建的视图,可是又不想编写针对该功能的表单,认证系统提供了几个内建的表单,位于django.contrib.auth.forms

内建的验证表单对他们处理的用户模型作了特定假设。若是你使用了_自定义的用户模型_,可能须要为验证系统定义你本身的表单。更多信息请见 _使用带有自定义用户模型的内建验证表单_的文档。

_class _AdminPasswordChangeForm[source]

管理界面中使用的表单,用于修改用户密码。

接受user做为第一个参数。

_class _AuthenticationForm[source]

用于用户登陆的表单。

接受request 做为第一个参数,它储存在表单实例中,被子类使用。

confirm_login_allowed(_user_)[source]

New in Django 1.7\.

一般, 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

或者只容许一些活动用户登陆进来:

class PickyAuthenticationForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not user.is_active:
            raise forms.ValidationError(
                _(),
                code='inactive',
            )
        if user.username.startswith('b'):
            raise forms.ValidationError(
                _(),
                code='no_b_users',
            )

_class _PasswordChangeForm[source]

一个表单,容许用户修改他们的密码。

_class _PasswordResetForm[source]

一个表单,用于生成和经过邮件发送一次性密码重置连接。

send_email(_subject_template_name_, _email_template_name_, _context_, _from_email_, _to_email_[, _html_email_template_name=None_])

New in Django 1.8\.

使用参数来发送EmailMultiAlternatives。能够覆盖来自定义邮件如何发送给用户。

<colgroup><col class="field-name"><col class="field-body"></colgroup>
Parameters: * subject_template_name – the template for the subject. * email_template_name – the template for the email body. * context – context passed to the subject_template, email_template, and html_email_template (if it is not None). * from_email – the sender’s email. * to_email – the email of the requester. * html_email_template_name – the template for the HTML body; defaults to None, in which case a plain text email is sent.

一般, save() 位于context中,并带有 password_reset() 向它的email上下文传递的一些变量。

_class _SetPasswordForm[source]

容许用户不输入旧密码修改密码的表单。

_class _UserChangeForm[source]

用户管理界面中修改用户信息和许可的表单。

_class _UserCreationForm[source]

用于建立新用户的表单。

模板中的认证数据

当你使用RequestContext时,当前登入的用户和它们的权限在_模板上下文_中能够访问。

技术细节

技术上讲,这些变量只有在你使用RequestContext并启用了'django.contrib.auth.context_processors.auth'上下文处理器时才能够在模板上下文中访问到。它是默认产生的配置文件。更多信息,参见_RequestContext 文档_

用户

当渲染RequestContext模板时,当前登陆的用户,多是User实例或者AnonymousUser实例,会存储在模板变量{{ user }}中:

{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
    <p>Welcome, new user. Please log in.</p>
{% endif %}

若是使用的不是RequestContext,则不能够访问该模板变量:

权限

当前登陆的用户的权限存储在模板变量{{ perms }}中。这是个 django.contrib.auth.context_processors实例的封装,他是一个对于模板友好的权限代理。

{{ 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 %}

在admin中管理用户

若是django.contrib.admindjango.contrib.auth这两个你都安装了,将能够经过admin方便地查看和管理用户、组和权限。能够像其它任何Django模型同样建立和删除用户。能够建立组,并分配权限给用户和组。admin中还会保存和显示对用户模型编辑的日志。

建立用户

在admin的主页,你应该能够在“Auth”部分看到“Users”连接。“Add user” 页面与标准admin页面不一样点在于它要求你在编辑用户的其它字段以前先选择一个用户名和密码。

另请注意:若是你想使得一个用户可以使用Django的admin站点建立其它用户, 你须要给他添加用户_和_修改用户的权限(例如,"Add user” 和“Change user” 权限)。若是一个帐号具备添加用户的权限可是没有权限修改他们,该帐号将不能添加用户。为何呢?由于若是你具备添加用户的权限,你将能够添加超级用户,这些超级用户将能够修改其余用户。因此Django同时要求添加权限_和_修改权限做为一种轻量的安全措施。

仔细考虑一下你是如何容许用户管理权限的。若是你了一个非超级用户编辑用户的能力,这和给他们超级用户的权限在最终效果上是同样的,由于他们将可以提高他们本身下面的用户的权限。

修改密码

用户密码不会显示在admin上(也不会存储在数据库中),可是会显示 _密码存储的细节_。 这个信息的显示中包含一条指向修改密码表单的连接,容许管理员修改用户的密码。

译者:Django 文档协做翻译小组,原文:Using the authentication system

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留做者署名和文章出处。

Django 文档协做翻译小组人手紧缺,有兴趣的朋友能够加入咱们,彻底公益性质。交流群:467338606。

相关文章
相关标签/搜索