django用户认证
django默认提供用户认证系统,它提供用户账号
,组
,权限
,cookie
,用户session
等功能,此文档解释了django如何实现这些功能,此外也介绍如何在项目中自定义用户认证系统 extend and customize
概述
django处理用户验证和授权.简而言之,身份验证如何证明我是我,授权是用户有什么权限。
认证系统包括:
- 用户
- 权限: (yes/no)标志,指定用户是否可通过检查,可以执行某些操作
- 组: 组和app关联,用户添加到组中,交集判断用户是否有权限
- 密码加密系统(hashing)
- Forms view logging user 用户表单,视图,限制返回内容等
- 可插拔后台系统
django认证系统是通用系统,不提供web认证系统一些特点,已有第三app已实现
- Password strength checking 密码强度检查
- Throttling of login attempts 登录尝试
- Authentication against third-parties (OAuth, for example) 第三方认证系统
安装
启用用户权限功能需要在以下安装组件提供相对应的功能django.contrib.auth
,默认以安装django-admin startproject
启动的时候,已将这些功能安装在INSTALLED_APPS
设定中
'django.contrib.auth'
包含核心认证框架,以及默认的model'django.contrib.contenttypes'
创建权限和user model关联
中间件设定MIDDLEWARE
:SessionMiddleware
manages sessions across requests.
AuthenticationMiddleware
associates users with requests using sessions.
Usage
- Working with User objects
- Permissions and authorization
- Authentication in web requests
- Managing users in the admin
API reference for the default implementation
Customizing Users and authentication
Using the Django authentication system¶
本文档适用于配置了django默认的认证系统,适用于很多常见的用户验证项目,权限和密码权限等需求。亦可进行自行扩展 extension and customization认证系统.
django提供了认证和授权,一般称为认证系统,功能有些耦合
User
objects¶
User
用户对象时身份验证系统的核心。 用户有自身的基本属性(个人详情信息),通过这些属性信息集合django认证的框架,以达到管理
和普通用户
不同类的对象
主要有以下属性:
See the full API documentation
for full reference, the documentation that follows is more task oriented.
Creating users¶
The most direct way to create users is to use the included create_user()
helper function 直接创建用户的函数:
from django.contrib.auth.models import User |
另一种创建用户的方法。If you have the Django admin installed, you can also create users interactively.
Creating superusers¶
创建管理员命令 createsuperuser
:
$ python manage.py createsuperuser --username=joe --email=joe@example.com |
输入以上命令后 --username
or --email
会有输入密码的请求.
Changing passwords¶
Django不是以明文存储密码 (clear text)在user model中, 而是hash (see documentation of how passwords are managed因此,不要试图直接操纵用户的密码属性。这就是创建用户时使用辅助函数的原因.
要更改用户的密码,您有几个选项:
manage.py changepassword *username*
提供一种从命令行更改用户密码的方法。它提示您更改给定用户的密码,您必须输入两次密码。如果两者都匹配,则新密码将立即更改。如果不提供用户,则命令将尝试更改用户名与当前登录的系统用户相匹配的密码(当前登录到此系统的用户)
另一种修改密码的方式 set_password()
:
from django.contrib.auth.models import User |
如果启用了admin后台也可以修改所有用户的密码authentication system’s admin pages.
Django也提供 views and forms 修改用户的密码
修改用户密码后期session信息会失效. 详情查看 Session invalidation on password change .
Authenticating users¶
authenticate
(request=None, *\credentials*)[source]¶使用
authenticate()
作为验证凭证. 将,username
和password
以关键字传入函数进行验证, 后台会进行检查 authentication backend, 返回一个User
对象如果通过检查. 如果验证不通过则抛出异常PermissionDenied
, 返回值为None
. For example:
from django.contrib.auth import authenticate |
request
是一个HttpRequest
生成的对象, 这是通过 authenticate()
后端方法认证
Changed in Django 1.11:
The optional request
argument was added.
Permissions and Authorization¶
Django有一个简单的权限系统。它提供了一种将权限分配给特定用户和用户组的方法。
它是由Django管理后台站点中使用,你也可以用于自己的代码中。
Django管理后台站点使用权限如下:
- 总的来说有三个权限
add, change,delete
- Access to view the “add” form and add an object is limited to users with the “add” permission for that type of object.
- Access to view the change list, view the “change” form and change an object is limited to users with the “change” permission for that type of object.
- Access to delete an object is limited to users with the “delete” permission for that type of object.
权限不仅可以设置每个对象类型,而且可以设置每个特定对象实例。通过使用has_add_permission()
, has_change_permission()
and has_delete_permission()
所提供的方法 ModelAdmin
类, 可以为同一类型的不同对象实例定制权限。
User
对象有两个多对多字段: groups
和user_permissions
. User
对象可以以与其他方法相同的方式访问它们的相关对象 Django model:
myuser.groups.set([group_list]) |
Default permissions¶
当django.contrib.auth
设定于 INSTALLED_APPS
setting中, 它将会三个默认权限 – add, change and delete
– 是在你安装的应用程序定义的每个Django模型默认创建.
这些权限将在运行时创建 manage.py migrate
; 第一次运行 migrate
在加入django.contrib.auth
到INSTALLED_APPS
, 将为所有以前安装的模型创建默认权限,以及当时安装的任何新model. 然后, 每次运行时,它将为新模型创建默认权限 manage.py migrate
(创建权限的函数连接到post_migrate
信号).
假设您有一个带有 app_label
foo
和model名为 Bar
, 要测试基本权限,您应该使用:
- add:
user.has_perm('foo.add_bar')
- change:
user.has_perm('foo.change_bar')
- delete:
user.has_perm('foo.delete_bar')
The Permission
很少直接访问模型
Groups¶
django.contrib.auth.models.Group
models是对用户进行分类的通用方法,因此您可以应用权限, 或其他标签,哪些用户. 一个用户可以属于一个或多个组.
组中的用户自动拥有授予该组的权限. For example, 如果组 Site editors
有权限 can_edit_home_page
, 该组中的任何用户都将获得该权限.
Beyond permissions, 组是一种方便的方法来分类用户给他们一些标签, 或扩展功能
. For example, 你可以创建一个组 'Special users'
, and you could write code that could, say, give them access to a members-only portion of your site, or send them members-only email messages (组内成员操作).
Programmatically creating permissions¶
当custom permissions 可以在模型中定义 Meta
类, 您还可以直接创建权限. For example, you can create the can_publish
permission for a BlogPost
model in myapp
:
from myapp.models import BlogPost |
然后可以将权限分配给 User
通过其 user_permissions
属性或 Group
通过其 permissions
属性.
Permission caching¶
The ModelBackend
在第一次为权限检查获取用户对象时,对其进行缓存. 对于请求响应周期来说,这通常是很好的,因为在添加权限后,通常不会立即检查权限(例如,在admin后台中)。如果您正在添加权限并立即检查它们, 例如,在测试或视图中, 最简单的解决方案是从数据库中重新获取用户. For example:
from django.contrib.auth.models import Permission, User |
Authentication in Web requests¶
Django 使用sessions 中间件将认证系统接入 request objects
.
这提供一个 request.user
表示当前用户的每个请求的属性.如果当前用户没有登录,则该属性将被设置为AnonymousUser
, otherwise it will be an instance of User
.
你可以把它们区分开来 is_authenticated
, 像这样:
if request.user.is_authenticated: |
How to log a user in¶
如果您有一个经过身份验证的用户要附加到当前会话-这是用 login()
函数.
从视图中记录一个用户已登录, 使用 login()
. 它需要一个 HttpRequest
对象和一个 User
对象. login()
将用户ID保存在会话中, using Django’s session framework.注意,匿名会话中的任何数据集都保留在用户登录后的会话中.这个示例演示了如何使用这两种方法authenticate()
和login()
:
from django.contrib.auth import authenticate, login |
Changed in Django 1.10:
在旧版本中,当您手动记录用户时,您必须*成功地验证用户authenticate()
在调用前 login()
. 现在您可以使用新的后端设置 backend
参数.
Selecting the authentication backend¶
当用户登录时,用户ID和用于身份验证的后端保存在用户会话中。这允许相同的authentication backend 在将来的请求中获取用户的详细信息. 在会话中保存的身份验证后端选择如下:
- 使用可选项
backend
参数, 如果已设定. - Use the value of the
user.backend
attribute, 这是目前. 这允许配对authenticate()
和login()
:authenticate()
集theuser.backend
attribute on the user object it returns. - Use the
backend
inAUTHENTICATION_BACKENDS
, if there is only one. - Otherwise, raise an exception.
In cases 1 and 2, the value of the backend
argument or the user.backend
attribute should be a dotted import path string (like that found in AUTHENTICATION_BACKENDS
), not the actual backend class.
How to log a user out¶
-
注销已登录用户
django.contrib.auth.login()
, 使用django.contrib.auth.logout()
within your view. 它需要一个HttpRequest
object and has no return value. Example:
from django.contrib.auth import logout |
Note that logout()
如果用户没有登录不会抛出任何的异常.
当你调用 logout()
, 当前请求的会话数据已完全清除。所有现有数据都已删除. 这是为了防止另一个人使用同一个Web浏览器登录并访问以前用户的会话数据. 如果您希望在登录后立即向用户可用的会话中放入任何内容, do that after calling django.contrib.auth.logout()
.
Limiting access to logged-in users¶
The raw way¶
限制页面访问的简单、原始方法是检查 request.user.is_authenticated
或者重定向到登录页面:
from django.conf import settings |
…or display an error message:from django.shortcuts import render
def my_view(request):
if not request.user.is_authenticated:
return render(request, 'myapp/login_error.html')
# ...