原文:https://djangobook.com/user-authentication-django/
User Authentication in Django
Django 用户验证
A significant percentage of modern, interactive websites allow some form of user interaction – from allowing simple comments on a blog, to full editorial control of articles on a news site. If a site offers any sort of ecommerce, authentication and authorization of paying customers is essential.
很多现代交互网站允许某种形式的用户交互,如允许评论博客,在新闻网站进行完整的文章编辑。
如果网站提供任意形式的电子商务,支付用户验证和授权十分关键。
Just managing users – lost usernames, forgotten passwords and keeping information up to date – can be a real pain. As a programmer, writing an authentication system can be even worse.
仅是管理用户 - 丢失用户名,忘记密码和保持信息更新 - 可能是十分痛苦的。作为程序员,写验证系统可能更糟糕。
Lucky for us, Django provides a default implementation for managing user accounts, groups, permissions and cookie-based user sessions out of the box.
幸运的是,Django提供了一种默认实现方式用来管理用户账户,组,权限和基于cookie的开箱即用的用户会话。
Like most things in Django, the default implementation is fully extensible and customizable to suit your project’s needs. So let’s jump right in.
像Django中的很多事情,默认的实现对于你的项目需求有很强的扩展性和可定制性。让我们开始。
Overview
概览
The Django authentication system handles both authentication and authorization. Briefly, authentication verifies a user is who they claim to be, and authorization determines what an authenticated user is allowed to do. Here the term authentication is used to refer to both tasks.
Django验证系统同时处理用户验证和授权。简单讲,验证是证明一个用户他是不是他声明的角色,授权决定了已经验证用户允许的操作。这里术语身份验证代表两个任务。
The authentication system consists of:
身份验证系统包括:
- Users
用户 - Permissions: Binary (yes/no) flags designating whether a user may perform a certain task
权限:二态(是/否)标志,描述用户是否可以执行一个任务。 - Groups: A generic way of applying labels and permissions to more than one user
组:一种常规方式,将标签和权限赋予超过单个用户 - A configurable password hashing system
可配置密码的散列系统 - Forms for managing user authentication and authorization
管理验证和授权的表格 - View tools for logging in users, or restricting content
用户日志或限制内容的查看工具 - A pluggable backend system
插件化的后台系统
The authentication system in Django aims to be very generic and doesn’t provide some features commonly found in web authentication systems. Solutions for some of these common problems have been implemented in third-party packages:
Django验证系统目的是通用,并且不提供web身份验证系统中的一般特性。一些普遍问题的解决方式已经被第三方包实现:
- Password strength checking
密码强度检查 - Throttling of login attempts
受限的登陆尝试 - Authentication against third-parties (OAuth, for example)
第三方的身份验证
Using The Django Authentication System
使用Django身份验证系统
Django’s authentication system in its default configuration has evolved to serve the most common project needs, handling a reasonably wide range of tasks, and has a careful implementation of passwords and permissions. For projects where authentication needs differ from the default, Django also supports extensive extension and customization of authentication.
默认配置的的Django身份验证系统已经发展到服务大多数的工程需要,处理合理范围内的任务,并有安全的密码和权限的实现。对于身份验证需求和默认配置不同的工程,Django也提供大量的扩展和定制的验证方式。
User Objects
使用对象
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. The primary attributes of the default user are:
用户对象是验证系统的核心。他们典型地表示用户在网站的交互并用来允许限制访问,记录用户配置,关联创建者的内容等。只有一类用户存在于Django验证框架,诸如,超级用户或管理员工的用户只是带有特殊属性设置的用户对象,不是特殊的用户对象类。默认用户的主要属性是:
username
password
email
first_name
last_name
CREATING SUPERUSERS
创建超级用户
Create superusers using the createsuperuser
command:
使用createsuperuser
创建超级用户
python manage.py createsuperuser --username=joe --email=joe@example.com
You will be prompted for a password. After you enter one, the user will be created immediately. If you leave off the --username
or the --email
options, it will prompt you for those values.
执行完命令之后,需要输入密码,然后用户就建立好了。如果没有输入--username
或--email
,那么他会提示你。
Creating Users
创建用户
The simplest, and least error prone way to create and manage users is through the Django admin. Django also provides built in views and forms to allow users to log in and out and change their own password. We will be looking at user management via the admin and generic user forms a bit later in this chapter, but first, let’s look at how we would handle user authentication directly.
最简单并且最少出错的创建并管理用户的方法是通过Django admin。Django也提供内置的视图和表单允许用户登陆登出和改变密码。本章后续章节,我们通过管理和通用用户表单看到用户管理。但是,先让我们看一下,如何直接地操作用户权限。
The most direct way to create users is to use the included create_user()
helper function:
创建用户最直接的方法是包含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()
Changing Passwords
修改密码
Django does not store raw (clear text) passwords on the user model, but only a hash. Because of this, do not attempt to manipulate the password attribute of the user directly. This is why a helper function is used when creating a user. To change a user’s password, you have two options:
Django在用户模型中不存储原始明文密码,但是只有一个hash。因为这样,用户不会直接尝试篡改密码。这就是当创建一个用户时,使用帮助者函数的原因。为了修改密码,我们有两个选择:
manage.py changepassword username
offers a method of changing a User’s password from the command line. It prompts you to change the password of a given user which you must enter twice. If they both match, the new password will be changed immediately. If you do not supply a user, the command will attempt to change the password of the user whose username matches the current system user
manage.py changepassword username
提供了一个从命令行修改用户密码的方法。它提示你输入两次新的密码。如果一样,则密码修改成功。如果没有指定用户,则尝试修改当前用户的密码。You can also change a password programmatically, using
set_password()
:
使用编程的方法修改密码,使用set_password()
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
Changing a user’s password will log out all their sessions if the SessionAuthenticationMiddleware
is enabled.
如果SessionAuthenticationMiddleware
可用,改变密码将会登出当前会话。
Permissions and Authorization
许可和授权
Django comes with a simple permissions system. It provides a way to assign permissions to specific
users and groups of users. It’s used by the Django admin site, but you’re welcome to use it in your own code. The Django admin site uses permissions as follows:
Django有一个简单的许可系统。提供方法来分配许可给指定的用户和组。它被用于Django管理网站,但是欢迎你在你的代码中使用它。Django管理网站这样使用许可:
Access to view the “add” form and add an object is limited to users with the “add” permission for that type of object.
查看添加表单和对象的使用权 仅限于对某类型对象有“add”权限的用户。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.
查看改变列表,查看“change”表单和改变对象的权限 仅限于某类型对象有“change”权限的用户Access to delete an object is limited to users with the “delete” permission for that type of object.
删除对象的权限 仅限于 对某类型对象有删除权限的用户
Permissions can be set not only per type of object, but also per specific object instance. By using the has_add_permission()
, has_change_permission()
and has_delete_permission()
methods provided by the ModelAdmin class, it’s possible to customize permissions for different object instances of the same type. 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.
不仅可以设置每个类型的对象,也可以设置每个特定对象实例。使用ModelAdmin类的has_add_permission()
, has_change_permission()
以及 has_delete_permission()
方法,它可能为一种类型不同对象实体定制权限。
用户对象可能又多对多的字段:groups
和 user_permissions
.用户对象可以访问相关的对象,用同样的方法想任何Django模型。
Default Permissions
默认权限
When django.contrib.auth
is listed in your INSTALLED_APPS
setting, it will ensure that three default permissions – add, change and delete – are created for each Django model defined in one of your installed applications. These permissions will be created for all new models each time you run manage.py migrate
.
当django.contrib.auth
在你的INSTALLED_APPS
中设置,它确保3个默认权限-添加,修改和删除-为安装的每一个应用的Django模型创建。每当你执行manage.py migrate
,这些权限被新的模型创建。
Groups
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. A user can belong to any number of groups. A user in a group automatically has the permissions granted to that group. For example, if the group Site editors has the permission can_edit_home_page
, any user in that group will have that permission.
组模型是一种通用的方式来分类用户,你可以分配权限和标签给这些用户。一个用户可以属于多个组。组里的用户自动拥有组所有的权限。举例,如果一个组有can_edit_home_page
权限,组内的的用户都有这个权限。
Beyond permissions, groups are a convenient way to categorize users to give them some label, or extended functionality. For example, you could create a group “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.
不仅权限,组很方便的管理用户,给予他们标签,或者扩展功能。例如,你可以创建组“Special users”并且,写代码说给予他们访问网站的会员部分,或者发送会员级别的邮件信息。
Programmatically Creating Permissions
编程创建权限
While custom permissions can be defined within a model’s Meta class, you can also create permissions directly. For example, you can create the can_publish
permission for a BookReview
model in books
:
虽然在模型元类中可以定义自定义类,你也可以直接创建权限。例如,你可以在books中为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)
The permission can then be assigned to a User via its user_permissions
attribute or to a Group via its permissions attribute.
通过user_permissions可以吧权限赋予yoghurt,或者通过权限属性给组。
Permission Caching
权限缓存
The ModelBackend caches permissions on the User object after the first time they need to be fetched for a permissions check. This is typically fine for the request-response cycle since permissions are not typically checked immediately after they are added (in the admin, for example).
在他们第一次用于权限检查之后,ModelBackend缓存用户对象的权限。对于请求-响应循环很好,因为权限在添加后不会立即被检查。
If you are adding permissions and checking them immediately afterward, in a test or view for example, the easiest solution is to re-fetch the User from the database. For example:
如果你添加权限后,立即检查他们,以测试或试图为例,最简单的解决方式是重新获取数据库中的用户。例如:
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
# ...