相当大比例的现代互动网站允许某种形式的用户互动 - 从允许在博客上发表简单评论到对新闻网站上的文章进行全面编辑控制。 如果一个网站提供任何类型的电子商务,支付客户的认证和授权是至关重要的。
仅仅管理用户 - 丢失用户名,忘记密码和保持信息更新 - 可能是一个真正的痛苦。 作为程序员,编写认证系统可能会更糟。
幸运的是,Django提供了一个默认实现,用于管理用户帐户,组,权限和开箱即用的基于cookie的用户会话。
像Django中的大多数情况一样,默认实现是完全可扩展的并且可定制以适应您的项目需求。 所以让我们直接进入。
概述
Django认证系统处理认证和授权。 简而言之,身份验证验证用户是他们自称的用户,并且授权决定允许经过身份验证的用户执行的操作。 这里使用术语认证来指代这两个任务。
认证系统由以下部分组成:
-
用户
-
权限:指定用户是否可以执行特定任务的二进制(是/否)标志
-
组:将标签和权限应用于多个用户的通用方法
-
一个可配置的密码散列系统
-
用于管理用户认证和授权的表单
-
查看登录用户或限制内容的工具
-
可插入的后端系统
Django中的认证系统的目标是非常通用,并且不提供Web认证系统中常见的一些功能。 第三方软件包已经实施了一些常见问题的解决方案:
- 密码强度检查
- 限制登录尝试
- 针对第三方的身份验证(例如,OAuth)
使用Django身份验证系统
Django的默认配置认证系统已经发展到满足最常见的项目需求,处理合理范围广泛的任务,并且仔细实现了密码和权限。 对于认证需求与默认不同的项目,Django还支持广泛的扩展和定制认证。
用户对象
用户对象是认证系统的核心。 它们通常代表与您的网站进行交互的人,并用于启用诸如限制访问,注册用户配置文件,将内容与创建者相关联等内容。在Django的身份验证框架中只存在一类用户,即超级用户或管理员工用户只是用户 设置了特殊属性的对象,而不是不同类的用户对象。 默认用户的主要属性是:
- username
- password
- first_name
- last_name
创建超级用户
使用createsuperuser命令创建超级用户:
python manage.py createsuperuser --username=joe --email=joe@example.com
系统会提示您输入密码。 输入一个后,用户将立即创建。 如果您不使用--username或--email选项,它会提示您输入这些值。
创建用户
创建和管理用户的最简单,最容易出错的方式是通过Django管理员。 Django还提供内置的视图和表单以允许用户登录和更改自己的密码。 我们将在本章的稍后部分通过管理员和通用用户表单来查看用户管理,但首先让我们看看我们将如何直接处理用户认证。
创建用户最直接的方法是使用包含的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不会在用户模型上存储原始(纯文本)密码,而只会存储一个哈希值。 因此,请勿尝试直接操作用户的密码属性。 这就是创建用户时使用帮助函数的原因。 要更改用户的密码,您有两种选
-
manage.py changepassword username提供了一种从命令行更改用户密码的方法。 它会提示您更改您必须输入两次的给定用户的密码。 如果两者都匹配,则新密码将立即更改。 如果您不提供用户,则该命令将尝试更改用户名与当前系统用户匹配的用户的密码。
-
您还可以使用set_password()以编程方式更改密码:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
如果启用SessionAuthenticationMiddleware,更改用户的密码将注销其所有会话。
权限和授权
Django带有一个简单的权限系统。 它提供了一种为特定用户和用户组分配权限的方法。 它由Django管理站点使用,但欢迎您在自己的代码中使用它。 Django管理站点使用权限如下:
-
访问查看“添加”表单并添加对象仅限于具有该类型对象的“添加”权限的用户。
-
访问查看更改列表,查看“更改”表单并更改对象仅限于具有该类型对象的“更改”权限的用户。
-
只有具有该类型对象的“删除”权限的用户才能访问删除对象。
权限不仅可以设置为每种类型的对象,还可以根据特定的对象实例设置。 通过使用ModelAdmin类提供的has_add_permission(),has_change_permission()和has_delete_permission()方法,可以为同一类型的不同对象实例定制权限。 用户对象有两个多对多字段:组和user_permissions。 用户对象可以像其他任何Django模型一样访问其相关对象。
默认权限
当django.contrib.auth在您的INSTALLED_APPS设置中列出时,它将确保为您安装的应用程序中定义的每个Django模型创建三个默认权限 - 添加,更改和删除。每次运行manage.py迁移时,都会为所有新模型创建这些权限。
组
django.contrib.auth.models.Group模型是对用户进行分类的通用方式,因此您可以将权限或其他标签应用于这些用户。用户可以属于任何数量的组。组中的用户自动拥有授予该组的权限。例如,如果网站编辑组拥有权限can_edit_home_page,那么该组中的任何用户都将拥有该权限。
除了权限之外,组是一种方便的方式来对用户进行分类,以给他们一些标签或扩展功能。例如,您可以创建一个“特殊用户”组,并且您可以编写代码,例如,可以让他们访问您网站的仅限会员的部分,或向他们发送仅限会员的电子邮件。
以编程方式创建权限
虽然自定义权限可以在模型的Meta类中定义,但您也可以直接创建权限。例如,您可以为书中的BookReview模型创建can_publish权限:
from books.models import BookReview
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BookReview)
permission = Permission.objects.create(codename='can_publish',
name='Can Publish Reviews',
content_type=content_type)
然后可以通过其user_permissions属性将权限分配给用户,或者通过其权限属性将权限分配给组。
权限缓存
ModelBackend在首次获取用户对象的权限检查后缓存对该用户对象的权限。 对于请求响应周期来说,这通常很好,因为权限添加后通常不会被立即检查(例如在管理员中)。
如果您正在添加权限并在之后立即检查它们,例如在测试或视图中,最简单的解决方案是从数据库中重新获取用户。 例如:
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('books.change_bar')
permission = Permission.objects.get(codename='change_bar')
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('books.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('books.change_bar') # True
# ...
网友评论