使用Django认证系统

本文档以默认配置解释了Django认证系统的用法。 这种配置已经发展到服务于最常见的项目需求,处理相当广泛的任务,并且仔细实现了密码和权限。 对于认证需求与默认不同的项目,Django支持广泛的extension and customization的认证。

Django身份验证同时提供身份验证和授权,通常称为身份验证系统,因为这些功能有些耦合。

User对象

User objects are the core of the authentication system. They typically represent the people interacting with your site and are used to enable things like restricting access, registering user profiles, associating content with creators etc. Only one class of user exists in Django’s authentication framework, i.e., 'superusers' or admin 'staff' users are just user objects with special attributes set, not different classes of user objects.

默认用户的主要属性是:

请参阅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管理员,也可以create users interactively

创建超级用户

使用createsuperuser命令创建超级用户:

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

系统会提示您输入密码。 输入一个后,用户将立即创建。 如果您离开--username--email选项,它会提示您输入这些值。

更改密码

Django不会在用户模型上存储原始(纯文本)密码,而只存储一个哈希值(有关详细信息,请参阅documentation of how passwords are managed 因此,不要试图直接操作用户的密码属性。 这就是为什么创建用户时使用帮助函数的原因。

要更改用户的密码,您有几个选择:

manage.py changepassword *username* offers a method of changing a user’s password from the command line. 它会提示您更改给定用户的密码,您必须输入两次密码。 如果两者匹配,则新密码将立即更改。 如果您不提供用户,则该命令将尝试更改用户名与当前系统用户匹配的密码。

您还可以使用set_password()以编程方式更改密码:

>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()

如果您安装了Django管理员,您也可以在authentication system’s admin pages上更改用户的密码。

Django还提供了可用于允许用户更改自己的密码的viewsforms

更改用户的密码将注销其所有会话。 有关详细信息,请参阅Session invalidation on password change

认证用户

authenticaterequest = None** credentials[source]

使用authenticate()来验证一组凭据。 它将缺省情况下的凭证作为关键字参数(usernamepassword),对每个authentication backend进行检查,并返回一个User对象是否对后端有效。 如果证书对任何后端无效,或者后端引发PermissionDenied,则返回None 例如:

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # A backend authenticated the credentials
else:
    # No backend authenticated the credentials

request is an optional HttpRequest which is passed on the authenticate() method of the authentication backends.

在Django 1.11中更改:

添加了可选的request参数。

注意

这是验证一组凭据的低级别方法;例如,它被RemoteUserMiddleware使用。 除非你正在编写自己的认证系统,否则你可能不会使用它。 相反,如果您正在寻找登录用户的方式,请使用LoginView

权限和授权

Django带有一个简单的权限系统。 它提供了一种为特定用户和用户组分配权限的方法。

Django管理站点使用它,但是欢迎您在自己的代码中使用它。

Django管理站点使用权限如下:

  • 访问查看“添加”窗体并添加一个对象仅限于具有该类型对象的“添加”权限的用户。
  • 访问查看更改列表,查看“更改”表单并更改对象仅限于具有该类型对象的“更改”权限的用户。
  • 访问删除对象仅限于具有该类型对象的“删除”权限的用户。

权限不仅可以设置每种类型的对象,还可以设置每个特定的对象实例。 通过使用ModelAdmin类提供的has_add_permission()has_change_permission()has_delete_permission()可以为同一类型的不同对象实例定制权限。

User objects have two many-to-many fields: groups and user_permissions. User objects can access their related objects in the same way as any other Django model:

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()

默认权限

INSTALLED_APPS设置中列出django.contrib.auth时,将确保为每个定义的Django模型创建三个默认权限 - add,change和delete - 您已安装的应用程序。

这些权限将在您运行manage.py migrate时创建。在将django.contrib.auth添加到INSTALLED_APPS之后,第一次运行migrate时,将为所有先前安装的模型创建默认权限,以及当时正在安装的任何新型号。 Afterward, it will create default permissions for new models each time you run manage.py migrate (the function that creates permissions is connected to the post_migrate signal).

假设你有一个名为app_label foo的应用程序和一个名为Bar的模型,为了测试基本权限,你应该使用:

  • add:user.has_perm('foo.add_bar')
  • 更改:user.has_perm('foo.change_bar')
  • 删除:user.has_perm('foo.delete_bar')

Permission模型很少直接访问。

¶ T0>

django.contrib.auth.models.Group models are a generic way of categorizing users so you can apply permissions, or some other label, to those users. 用户可以属于任何数量的组。

组中的用户自动具有授予该组的权限。 例如,如果组Site editors具有can_edit_home_page权限,那么该组中的任何用户将拥有该权限。

除了权限,组是一种方便的方式来分类用户给他们一些标签,或扩展功能。 例如,你可以创建一个组'Special users',你可以编写代码,可以让他们访问成员只是您的网站的一部分,或向他们发送会员专用的电子邮件。

以编程方式创建权限

虽然可以在模型的Meta类中定义custom permissions,但也可以直接创建权限。 例如,您可以在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,
)

The permission can then be assigned to a User via its user_permissions attribute or to a Group via its permissions attribute.

权限缓存

在第一次需要获取权限检查之后,ModelBackend缓存用户对象的权限。 对于请求 - 响应周期,这通常很好,因为权限通常不会在添加后立即检查(例如,在管理员中)。 如果您正在添加权限并在之后立即检查权限,则在测试或视图中,例如,最简单的解决方案是从数据库重新获取用户。 例如:

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

    ...

Web请求中的认证

Django使用sessions和中间件将认证系统挂接到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)[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(request, username=username, password=password)
    if user is not None:
        login(request, user)
        # Redirect to a success page.
        ...
    else:
        # Return an 'invalid login' error message.
        ...

选择认证后端

用户登录时,用户的ID和用于身份验证的后端都保存在用户的会话中。 这允许相同的authentication backend在将来的请求中获取用户的详细信息。 要保存在会话中的认证后端选择如下:

  1. 如果提供,请使用可选的backend参数的值。
  2. 使用user.backend属性的值(如果存在)。 This allows pairing authenticate() and login(): authenticate() sets the user.backend attribute on the user object it returns.
  3. 如果只有一个,则使用AUTHENTICATION_BACKENDS中的backend
  4. 否则,引发一个异常。

在情况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_requiredredirect_field_name ='next'login_url = None[source] t5 >

作为一个快捷方式,您可以使用方便的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):
    ...

Note that if you provide a value to redirect_field_name, you will most likely need to customize your login template as well, since the template context variable which stores the redirect path will use the value of redirect_field_name as its key rather than "next" (the default).

login_required() also takes an optional login_url parameter. 例:

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

path('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 T0> ¶ T1>

如果一个视图使用这个mixin,那么所有未经身份验证的用户的请求将被重定向到登录页面,或者显示一个HTTP 403 Forbidden错误,这取决于raise_exception参数。

您可以设置AccessMixin的任何参数来自定义处理未经授权的用户:

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

注意

就像login_required装饰器一样,这个mixin不检查用户的is_active标志,但默认的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')[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() takes a required argument: a callable that takes a User object and returns True if the user is allowed to view the page. Note that user_passes_test() does not automatically check that the User is not anonymous.

user_passes_test() takes two optional arguments:

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):
    ...
UserPassesTestMixin T0> ¶ T1>

当使用class-based views时,可以使用UserPassesTestMixin来执行此操作。

test_func T0>()¶ T1>

您必须重写该类的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 T0>()¶ T1>

You can also override the get_test_func() method to have the mixin use a differently named function for its checks (instead of 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):
    ...

If TestMixin1 would call super() and take that result into account, TestMixin1 wouldn’t work standalone anymore.

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

Just like the has_perm() method, permission names take the form "<app label>.<permission codename>" (i.e. polls.can_vote for a permission on a model in the polls application).

装饰器也可能需要迭代权限,在这种情况下,用户必须拥有所有权限才能访问视图。

请注意,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):
    ...

The PermissionRequiredMixin mixin

要将权限检查应用于class-based views,您可以使用PermissionRequiredMixin

PermissionRequiredMixin T0> ¶ T1>

这个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 T0>()¶ T1>

返回mixin使用的权限名称的迭代。 默认为permission_required属性,必要时转换为元组。

has_permission T0>()¶ T1>

返回一个布尔值,表示当前用户是否有权执行装饰视图。 默认情况下,这会返回调用has_perms()get_permission_required()返回的权限列表的结果。

在基于类的视图中重定向未授权的请求

为了缓解class-based views中访问限制的处理,可以使用AccessMixin将用户重定向到登录页面或发出HTTP 403 Forbidden响应。

AccessMixin T0> ¶ T1>
LOGIN_URL T0> ¶ T1>

get_login_url()的默认返回值。 Defaults to None in which case get_login_url() falls back to settings.LOGIN_URL.

permission_denied_message T0> ¶ T1>

get_permission_denied_message()的默认返回值。 缺省为空字符串。

redirect_field_name T0> ¶ T1>

get_redirect_field_name()的默认返回值。 默认为"next"

raise_exception T0> ¶ T1>

如果此属性设置为True,则将引发PermissionDenied异常,而不是重定向。 默认为False

get_login_url T0>()¶ T1>

返回未通过测试的用户将被重定向到的URL。 如果已设置,则返回login_url,否则返回settings.LOGIN_URL

get_permission_denied_message T0>()¶ T1>

raise_exceptionTrue时,可以使用此方法来控制传递给错误处理程序以显示给用户的错误消息。 默认返回permission_denied_message属性。

get_redirect_field_name T0>()¶ T1>

返回将包含用户在成功登录后应该重定向到的URL的查询参数的名称。 如果将其设置为None,则不会添加查询参数。 默认返回redirect_field_name属性。

handle_no_permission T0>()¶ T1>

根据raise_exception的值,该方法或者引发一个PermissionDenied异常或者将用户重定向到login_url,可选地包括redirect_field_name如果设置。

会话无效更改密码

如果您的AUTH_USER_MODEL继承自AbstractBaseUser或者实现了自己的get_session_auth_hash()方法,则认证的会话将包含此函数返回的散列。 AbstractBaseUser的情况下,这是密码字段的HMAC。 Django验证会话中每个请求的散列值与请求期间计算的散列值是否匹配。 这允许用户通过更改密码来注销其所有会话。

The default password change views included with Django, PasswordChangeView and the user_change_password view in the django.contrib.auth admin, update the session with the new password hash so that a user changing their own password won’t log themselves out. 如果您有一个自定义的密码更改视图,并希望有类似的行为,请使用update_session_auth_hash()函数。

update_session_auth_hash请求用户[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:
        ...
在Django 1.11中更改:

会话密钥的旋转被添加。

注意

由于get_session_auth_hash()基于SECRET_KEY,因此更新站点以使用新的秘密将使所有现有会话无效。

认证视图

Django提供了几个视图,可以用来处理登录,注销和密码管理。 这些使用stock auth forms,但你也可以传递你自己的形式。

Django不提供认证视图的默认模板。 您应该为要使用的视图创建自己的模板。 模板上下文记录在每个视图中,请参阅All authentication views

使用视图

在您的项目中实现这些视图有不同的方法。 最简单的方法是将提供的URLconf包含在您自己的URLconf中的django.contrib.auth.urls中,例如:

urlpatterns = [
    path('accounts/', include('django.contrib.auth.urls')),
]

这将包括以下网址格式:

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'),
    ),
]

所有的视图都是class-based,它允许你通过子类化来轻松地定制它们。

所有认证视图

This is a list with all the views django.contrib.auth provides. 有关实施细节,请参阅Using the views

loginrequesttemplate_name =`registration / login.html`redirect_field_name ='next' authentication_form = AuthenticationFormextra_context = Noneredirect_authenticated_user = False

自1.11版以来已弃用: 基于login函数的视图应该由基于类的LoginView替换。

这个视图的可选参数类似于基于类的LoginView属性。

LoginView T0> ¶ T1>
Django 1.11新增功能

网址名称: 登录 T0>

有关使用指定URL模式的详细信息,请参阅the URL documentation

属性:

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

  • redirect_field_name: The name of a GET field containing the URL to redirect to after login. 默认为next

  • authentication_form:用于验证的可调用(通常只是一个表单类)。 默认为AuthenticationForm

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

  • redirect_authenticated_user: A boolean that controls whether or not authenticated users accessing the login page will be redirected as if they had just successfully logged in. 默认为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:除了request.get_host()之外,主机的set,登录后可以安全地重定向。 默认为一个空的set

以下是LoginView所做的:

  • 如果通过GET调用,它会显示一个登录表单,并将其发送到相同的URL。 更多关于这一点。
  • 如果通过POST通过用户提交的凭据进行调用,则会尝试登录用户。 如果登录成功,则视图将重定向到next中指定的URL。 如果next未提供,则重定向到settings.LOGIN_REDIRECT_URL(默认为/accounts/profile/)。 如果登录不成功,则重新显示登录表单。

您有责任为登录模板提供html,默认情况下称为registration/login.html 这个模板获得了四个模板上下文变量:

如果您不想调用模板registration/login.html,则可以通过template_name参数将额外参数传递给as_view方法在你的URLconf。 例如,这个URLconf行会使用myapp/login.html来代替:

path('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属性来使用自定义身份验证表单。 This form must accept a request keyword argument in its __init__() method and provide a get_user() method which returns the authenticated user object (this method is only ever called after successful form validation).

注销请求next_page =无template_name ='registration / logged_out.html'redirect_field_name ='next'extra_context = None

自1.11版以来已弃用: 应该用基于类的LogoutView替换logout基于函数的视图。

这个视图的可选参数类似于基于类的LogoutView属性。

LogoutView T0> ¶ T1>
Django 1.11新增功能

记录用户。

网址名称: 注销 T0>

属性:

  • next_page:注销后重定向到的URL。 默认为settings.LOGOUT_REDIRECT_URL
  • template_name:登出用户后要显示的模板的全名。 默认为registration/logged_out.html
  • redirect_field_name: The name of a GET field containing the URL to redirect to after log out. 默认为next 如果传递给定的GET参数,则覆盖next_page URL。
  • extra_context:将被添加到传递给模板的默认上下文数据的上下文数据字典。
  • success_url_allowed_hosts:除了request.get_host()之外,主机的set在注销后可以安全地重定向。 默认为一个空的set

模板上下文:

  • title: The string “Logged out”, localized.
  • site:当前Site,根据SITE_ID设置。 如果您没有安装网站框架,则会将其设置为RequestSite的实例,该实例从当前的HttpRequest派生站点名称和域。
  • site_namesite.name的别名。 如果您没有安装网站框架,则会将其设置为request.META['SERVER_NAME']的值。 有关网站的更多信息,请参阅The “sites” framework
logout_then_loginrequestlogin_url = Noneextra_context = None

记录用户,然后重定向到登录页面。

网址名称: 没有提供默认网址

可选参数:

  • login_url:重定向到的登录页面的URL。 如果未提供,则默认为settings.LOGIN_URL
  • extra_context:将被添加到传递给模板的默认上下文数据的上下文数据字典。

自1.11版以来已弃用: 未使用的extra_context参数已被弃用,并将在Django 2.1中被删除。

password_changerequesttemplate_name ='registration / password_change_form.html'post_change_redirect = Nonepassword_change_form = PasswordChangeFormextra_context = None

自1.11版以来已弃用: 应该用基于类的PasswordChangeView替换password_change基于函数的视图。

这个视图的可选参数类似于基于类的PasswordChangeView属性,除了post_change_redirectpassword_change_form参数映射到success_urlform_class属性。

PasswordChangeView T0> ¶ T1>
Django 1.11新增功能

网址名称: password_change T0>

允许用户更改密码。

属性:

  • 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', extra_context=None)

自1.11版以来已弃用: 应该用基于类的PasswordChangeDoneView替换password_change_done基于函数的视图。

这个视图的可选参数类似于基于类的PasswordChangeDoneView属性。

PasswordChangeDoneView T0> ¶ T1>
Django 1.11新增功能

网址名称: password_change_done T0>

用户更改密码后显示的页面。

属性:

  • 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, extra_context=None, html_email_template_name=None, extra_email_context=None)

自1.11版以来已弃用: 应该用基于类的PasswordResetView替换password_reset基于函数的视图。

这个视图的可选参数类似于基于类的PasswordResetView属性,除了post_reset_redirectpassword_reset_form参数映射到success_urlform_class属性。

PasswordResetView T0> ¶ T1>
Django 1.11新增功能

网址名称: password_reset T0>

允许用户通过生成一次性使用链接重置密码,该链接可用于重置密码,并将该链接发送到用户的注册电子邮件地址。

如果提供的电子邮件地址在系统中不存在,则此视图不会发送电子邮件,但用户也不会收到任何错误消息。 这可以防止信息泄露给潜在的攻击者。 如果您想在这种情况下提供错误消息,您可以继承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: Instance of the class to check the one time link. 这将默认为default_token_generator,它是django.contrib.auth.tokens.PasswordResetTokenGenerator的一个实例。
  • success_url:成功的密码重置请求后重定向到的URL。
  • from_email:有效的电子邮件地址。 默认情况下,Django使用DEFAULT_FROM_EMAIL
  • extra_context:将被添加到传递给模板的默认上下文数据的上下文数据字典。
  • html_email_template_name: The full name of a template to use for generating a text/html multipart email with the password reset link. 默认情况下,不发送HTML电子邮件。
  • extra_email_context: A dictionary of context data that will be available in the email template.

模板上下文:

  • form:用于重置用户密码的表单(参见上面的form_class)。

邮件模板上下文:

  • emailuser.email的别名
  • user:当前User,根据email表单字段。 只有活跃用户才能重置密码(User.is_active True)。
  • site_namesite.name的别名。 如果您没有安装网站框架,则会将其设置为request.META['SERVER_NAME']的值。 有关网站的更多信息,请参阅The “sites” framework
  • domainsite.domain的别名。 如果您没有安装网站框架,则会将其设置为request.get_host()的值。
  • protocol: http or https
  • uid:以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', extra_context=None)

自1.11版以来已弃用: 应该用基于类的PasswordResetDoneView替换password_reset_done基于函数的视图。

这个视图的可选参数类似于基于类的PasswordResetDoneView属性。

PasswordResetDoneView T0> ¶ T1>
Django 1.11新增功能

网址名称: password_reset_done T0>

在用户通过电子邮件发送一个链接重置他们的密码后显示的页面。 如果PasswordResetView没有明确的success_url URL集合,则默认调用此视图。

注意

如果提供的电子邮件地址在系统中不存在,用户处于非活动状态,或者密码不可用,用户仍将被重定向到该视图,但不会发送电子邮件。

属性:

  • 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, extra_context=None)

自1.11版以来已弃用: The password_reset_confirm function-based view should be replaced by the class-based PasswordResetConfirmView.

这个视图的可选参数类似于基于类的PasswordResetConfirmView属性,除了post_reset_redirectset_password_form参数映射到success_urlform_class属性。

PasswordResetConfirmView T0> ¶ T1>
Django 1.11新增功能

网址名称: password_reset_confirm T0>

提供一个输入新密码的表单。

来自网址的关键字参数:

  • uidb64:用64位编码的用户id。
  • token:令牌来检查密码是否有效。

属性:

  • template_name:显示确认密码视图的模板的全名。 默认值是registration/password_reset_confirm.html
  • token_generator: Instance of the class to check the password. 这将默认为default_token_generator,它是django.contrib.auth.tokens.PasswordResetTokenGenerator的一个实例。
  • post_reset_login:一个布尔值,指示用户是否应该在密码重置成功后自动进行身份验证。 默认为False
  • post_reset_login_backend:当post_reset_loginTrue时,验证用户时使用的身份验证后端的虚线路径。 只有配置了多个AUTHENTICATION_BACKENDS时才需要。 默认为None
  • form_class:将用于设置密码的表单。 默认为SetPasswordForm
  • success_url:完成密码重置后重定向的URL。 默认为'password_reset_complete'
  • extra_context:将被添加到传递给模板的默认上下文数据的上下文数据字典。

模板上下文:

  • form:设置新用户密码的形式(参见上面的set_password_form)。
  • validlink:布尔值,如果链接(uidb64token的组合)有效或未使用,则为True。
password_reset_complete(request, template_name='registration/password_reset_complete.html', extra_context=None)

自1.11版以来已弃用: 应该用基于类的PasswordResetCompleteView替换password_reset_complete基于函数的视图。

这个视图的可选参数类似于基于类的PasswordResetCompleteView属性。

PasswordResetCompleteView T0> ¶ T1>
Django 1.11新增功能

网址名称: password_reset_complete T0>

显示通知用户密码已成功更改的视图。

属性:

  • 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: The name of a GET field containing the URL to redirect to after log out. 如果给定的GET参数被传递,则覆盖next

内置表单

如果您不想使用内置视图,但为了方便不必为此功能编写表单,认证系统会提供几个内置表单,位于django.contrib.auth.forms

注意

内置的认证表单对他们正在使用的用户模型做了一定的假设。 如果您使用custom user model,则可能需要为认证系统定义自己的表单。 有关更多信息,请参阅有关使用自定义用户模型的内置身份验证表单的using the built-in authentication forms with custom user models

AdminPasswordChangeForm T0> ¶ T1>

管理界面中用于更改用户密码的表单。

user作为第一个参数。

AuthenticationForm T0> ¶ T1>

登录用户的表单。

request作为其第一个位置参数,存储在表单实例中供子类使用。

confirm_login_allowed T0>(用户 T1>)¶ T2>

默认情况下,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',
            )
PasswordChangeForm T0> ¶ T1>

允许用户更改密码的表单。

PasswordResetForm T0> ¶ T1>

用于生成并通过一次性使用链接发送电子邮件以重置用户密码的表单。

发送邮件subject_template_nameemail_template_name上下文from_emailto_email ,html_email_template_name = None

使用参数发送EmailMultiAlternatives 可以被覆盖以定制如何将电子邮件发送给用户。

参数:
  • subject_template_name – the template for the subject.
  • email_template_name - 电子邮件正文的模板。
  • context - 传递给subject_templateemail_templatehtml_email_template的上下文(如果不是None
  • from_email - 发件人的电子邮件。
  • to_email - 请求者的电子邮件。
  • html_email_template_name – the template for the HTML body; defaults to None, in which case a plain text email is sent.

缺省情况下,save()使用PasswordResetView传递给其电子邮件上下文的相同变量填充context

SetPasswordForm T0> ¶ T1>

一种让用户在不输入旧密码的情况下更改密码的表单。

UserChangeForm T0> ¶ T1>

管理界面中用于更改用户信息和权限的表单。

UserCreationForm T0> ¶ T1>

用于创建新用户的ModelForm

它有三个字段:username(来自用户模型),password1password2 It verifies that password1 and password2 match, validates the password using validate_password(), and sets the user’s password using set_password().

模板中的认证数据

当您使用RequestContext时,当前登录的用户及其权限在template context中可用。

技术性

从技术上讲,如果使用RequestContext'django.contrib.auth.context_processors.auth'上下文处理器启用了这些变量,那么这些变量只能在模板上下文中使用。 它在默认生成的设置文件中。 有关更多信息,请参阅RequestContext docs

用户¶ T0>

When rendering a template RequestContext, the currently logged-in user, either a User instance or an AnonymousUser instance, is stored in the template variable {{ 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,则此模板上下文变量不可用。

权限¶ T0>

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

评估作为布尔值的{{ perms }}的单个属性查找是User.has_module_perms() 例如,要检查登录的用户是否在foo应用程序中有任何权限:

{% if perms.foo %}

Evaluating a two-level-attribute lookup as a boolean is a proxy to User.has_perm(). 例如,要检查登录用户是否具有权限foo.can_vote

{% if perms.foo.can_vote %}

以下是检查模板中权限的更完整示例:

{% 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 'foo' in perms %}
    {% if 'foo.can_vote' in perms %}
        <p>In lookup works, too.</p>
    {% endif %}
{% endif %}

管理admin 中的用户

当您安装了django.contrib.admindjango.contrib.auth时,管理员可以方便地查看和管理用户,组和权限。 用户可以像任何Django模型一样创建和删除。 可以创建组,并且可以将权限分配给用户或组。 用户对管理员模型进行编辑的日志也被存储和显示。

创建用户

您应该在管理主索引页面的“身份验证”部分中看到“用户”链接。 “添加用户”管理页面与标准管理页面的不同之处在于,您需要先选择用户名和密码,然后才允许编辑用户字段的其余部分。

另外请注意:如果你想让一个用户帐号能够使用Django管理站点创建用户,你需要给他们添加用户的权限,即更改用户(即“添加用户”和“更改用户”权限)。 如果某个帐户有权限添加用户,但不能更改他们,那么该帐户将无法添加用户。 为什么? 因为如果您有权限添加用户,则您有权创建超级用户,然后又可以更改其他用户。 所以Django需要添加更改权限作为一个轻微的安全措施。

请考虑如何让用户管理权限。 如果您授予非超级用户编辑用户的权限,则这与为其授予超级用户身份最终是一样的,因为他们可以提升包括他们自己在内的用户的权限!

更改密码

用户密码不显示在管理员(也不存储在数据库)中,但会显示password storage details 包含在这个信息显示中的是一个密码更改表单的链接,允许管理员更改用户密码。