一、Django默认的用户认证系统
Django 自带一个用户验证系统。它负责处理用户账号、组、权限和基于cookie的用户会话。
Django 验证系统处理验证和授权。简单来说,验证检验用户是否是他们的用户,授权决定已验证用户能做什么。这里的术语验证用于指代这两个任务。
认证系统由以下部分组成:
- 用户
- 权限:二进制(是/否)标识指定用户是否可以执行特定任务。
- 组:将标签和权限应用于多个用户的一般方法。
- 可配置的密码哈希化系统
- 为登录用户或限制内容提供表单和视图工具
- 可插拔的后端系统
Django 里的验证系统旨在通用化,不提供一些常见的 web 验证系统的特性。其中一些常见问题的解决方案已在第三方包中实现。
- 密码强度检查
- 限制登录尝试
- 针对第三方的身份验证(例如OAuth)
- 对象级权限
二、用户管理(User)
Django的用户管理通过User模型类处理。
2.1 User模型的字段
username
:必要的。150 个字符或以下。用户名可包含字母数字、_
、@
、+
、.
和 -
字符。
first_name
:可空字段。150 个字符或更少。
last_name
:可空字段。150 个字符或更少。
email
:可空字段。电子邮件地址。
password
:必填字段。一个密码的哈希值和元数据。(Django 不存储原始密码。)原始密码可以任意长,可以包含任何字符。
groups:
多对多关系到 Group
user_permissions
:多对多关系到 Permission
is_staff
:布尔型。指定该用户是否可以访问管理站点。
is_active:
布尔值。指定该用户账户是否应该被视为活跃账户。我们建议你把这个标志设置为 False
,而不是删除账户;这样,如果你的应用程序对用户有任何外键,外键就不会被破坏。
is_superuser
:布尔值。指定该用户拥有所有权限,而不用一个个开启权限。
last_login:
用户最后一次登录的日期时间。
date_joined
:指定账户创建时间的日期时间。帐户创建时,默认设置为当前日期/时间。
2.2 User模型的属性
is_authenticated
:只读属性,始终返回 True
(匿名用 护AnonymousUser.is_authenticated
始终返回 False
),可通过该方法确认用户是否为用户列表中的用户。
is_anonymous:
只读属性,总是 False
。这是区分 User 和 AnonymousUser 对象的一种方式。一般来说,你应该优先使用 is_authenticated 来代替这个属性。
三、User基本操作
需要引入User模块:
from django.contrib.auth.models import User
3.1 查询所有用户
# 获取所有用户
users = User.objects.all()
response.append(f"All User : {users.count()}")
for user in users:
response.append(f"-- {user.get_username()}")
3.2 添加新用户
user1 = User.objects.create_user(username="User3",password="123456")
user1.save()
response.append(f"New User : {user1.get_username()}")
user2 = User.objects.create_user(username="User4",password="123456")
response.append(f"New User : {user2.get_username()}")
3.3 修改用户信息
user = User.objects.get(username = "User1")
response.append(f"Old UserName : {user.get_username()}")
user.username = "New User"
user.save()
user = User.objects.get(username = "New User")
response.append(f"New UserName : {user.get_username()}")
3.4 修改密码
user = User.objects.get(username = "User3")
response.append(f"Old Password : {user.password}")
user.set_password("888888")
user.save()
user = User.objects.get(username = "User3")
response.append(f"New Password : {user.password}")
3.5 用户验证
使用 authenticate() 来验证用户,使用时需要引入函数。它使用 username
和 password
作为参数来验证,对每个身份验证后端( authentication backend ` )进行检查。如果后端验证有效,则返回一个 :class:`~django.contrib.auth.models.User 对象。如果后端引发 PermissionDenied 错误,将返回 None
。
from django.contrib.auth import authenticate
user = authenticate(username= "New User", password = "123456")
if user is not None:
response.append(f"User is exist : {user.get_username()}")
else:
response.append(f"User is not exist.")
四、权限管理
4.1 创建权限
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from serverapp.models import Person
def CreatePermission(request:HttpRequest, new_permission:str):
"""Create perssion"""
content_type = ContentType.objects.get_for_model(Person)
permission, result = Permission.objects.get_or_create(
codename = new_permission,
name = f"Can {new_permission}",
content_type = content_type,
)
return HttpResponse("{0}".format(permission))
权限可以在权限表中查看到:
4.2 用户权限管理
使用User对象的groups
和 user_permissions进行权限设置。
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()
4.3 用户登录
from django.contrib.auth import login
def login_user(request:HttpRequest,pk:int):
"""Create perssion"""
login_user = User.objects.get(pk=pk)
login(request, login_user)
return HttpResponse("The user {0} login.".format(login_user.get_username()))
4.4 用户登出
from django.contrib.auth import logout
def logout_user(request:HttpRequest):
"""Create perssion"""
logout(request)
return HttpResponse("The user {0} logout.".format(request.user.get_username()))
4.5 限制未登录用户的访问
4.5.1 检查request.user.is_authenticated 状态
def login_confirm_raw(request:HttpRequest):
"""Create perssion"""
if not request.user.is_authenticated:
return HttpResponse("The user {0} doesn't login.".format(request.user.get_username()))
else:
return HttpResponse("The user {0} has login.".format(request.user.get_username()))
未登录时:
登陆用户:
重新确认用户是否登录:
4.5.2 使用login_required
装饰器
from django.contrib.auth.decorators import login_required
@login_required
def login_confirm(request:HttpRequest):
"""Create perssion"""
if not request.user.is_authenticated:
return HttpResponse("The user {0} doesn't login.".format(request.user.get_username()))
else:
return HttpResponse("The user {0} has login.".format(request.user.get_username()))
4.6 限制已登录的用户
除了直接对用户信息进行判定外,亦可以使用user_passes_test
装饰器进行判定。
from django.contrib.auth.decorators import user_passes_test
def username_check(user:User):
"""Check username"""
return user.username.startswith("User")
@user_passes_test(username_check)
def check(request:HttpRequest):
"""check user"""
return HttpResponse("The username {0} is right.".format(request.user.get_username()))
user_passes_test() 接受一个必要的参数:一个带有:class:~django.contrib.auth.models.User 对象的调用,如果允许用户访问这个页面,则返回 True
。注意,user_passes_test() 不会自动检查用户是否匿名。
user_passes_test() 可以传递两个可选参数:
login_url
允许你指定用户没有通过测试时跳转的地址。它可能是一个登录页面,如果你没指定,默认是 settings.LOGIN_URL 。
redirect_field_name
与 login_required() 相同。如果你想把没通过检查的用户重定向到没有 "next page" 的非登录页面时,把它设置为 None
,这样它会在 URL 中移除。
4.7 权限访问装饰器(permission_required
)
使用permission_required装饰器,可以快捷的确认用户是否有特定的权限。
from django.contrib.auth.decorators import permission_required
@permission_required("""serverapp.add_person""")
def check_permission(request:HttpRequest):
"""Check user permission"""
return HttpResponse("The user {0} has permission.".format(request.user.get_username()))
有权限时:
无权限时: