python-Django基本流程原理02-认证系统
* django认证系统 *
一. Django默认用户认证系统
Django 认证提供了实现认证(authentiaction)和授权(authorization)两种功能的用户认证系统–auth 使用的存储表auth_user
参考文档点这里
Django用户认证系统它处理用户账号、组、权限以及基于cookie的用户会话。
- Django认证系统同时处理认证和授权:
- 认证:验证一个用户是否可用于账号登录。
- 授权:授权决定一个通过了认证的用户被允许做什么。
- Django认证系统包含的内容:
- 用户:用户模型类、用户认证。
- 权限:标识一个用户是否可以做一个特定的任务。
- 组:对多个具有相同权限的用户进行统一管理。
- 密码:一个可配置的密码哈希系统,设置密码、密码校验。
主要模块:
from django.contrib import auth //包含身份验证框架的核心及其默认模型 from django.contrib import contenttypes //是Django内容类型系统,它允许权限与你创建的模型关联。
模块详解:
from django.contrib import auth //确保你的每个 Django 模型被创建时有四个默认权限:添加、修改、删除和查看 from django.contrib.auth.models import User //user对象 from django.contrib.auth import authenticate // authenticate验证用户 from django.contrib.auth.models import Group //对用户进行分类的通用方法
user对象的权限操作:
django.contrib.auth.models.User” 对象有两个多对多字段:groups
和user_permissions
可以通过user_permissions
属性将权限分配给user
,或通过permissions
属性分配给group
操作:
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()
我们看一下基本如何使用
二. 用户认证系统实现实例
主要用到的几个方法:
- create_user 创建用户
- authenticate 验证登录
- login 记住用户的登录状态
- logout 退出登录
- is_authenticated 判断用户是否登录
login_required 判断用户是否登录的装饰器
1. 创建用户:
User 对象的主要属性有 username, password, email, first_name, last_name
1.1 普通的创建用户
from django.contrib.auth.models import User
user = User.objects.create_user('yym', 'yym@yiyumo.com', 'yympassword')
~ 创建超级用户指令 python manage.py createsuperuser –username=yym --email=yym@yym.com ~
1.2 更改密码
from django.contrib.auth.models import User
u = User.objects.get(username='yym')
u.set_password('new password')
u.save()
~ 更改密码指令 python manage.py changepassword username ~
2. 验证用户
使用
authenticate()
来验证用户。它使用username
和password
作为参数来验证,对每个身份验证后端进行检查。如果后端验证有效,则返回一个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
3. 权限
当 INSTALLED_APPS 设置了 django.contrib.auth 时,它将确保你的每个 Django 模型被创建时有四个默认权限:添加、修改、删除和查看
3.1 创建权限
from car.models import UseCar
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
# 为车辆模型创建可发布接单的权限
content_type = ContentType.objects.get_for_model(UseCar)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)
3.2 权限缓存
第一次需要获取用户对象的权限检查时,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 car.models import UseCar
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('car.change_usecar')
content_type = ContentType.objects.get_for_model(UseCar)
permission = Permission.objects.get(
codename='change_usecar',
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('car.change_usecar') # 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('car.change_usecar') # True
...
4. Web 请求的认证
4.1 web请求的验证
Django 使用 sessions 和中间件将身份验证系统挂接到请求对象中
它们在每次请求中都会提供request.user
属性。如果当前没有用户登录,这个属性将会被设置为AnonymousUser
,否则将会被设置为User
实例。
使用user
的属性is_authenticated
来区分 用户是否已通过身份验证
使用user
的属性is_anonymous
来区分User和AnonymousUser 对象
if request.user.is_authenticated:
user
...
else:
pass
4.2 用户的登录
将已验证的用户想附加到当前会话(session)中将通过 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.
...
4.3 用户的登出
将已验证的用户想从当前会话(session)中将删除通过 logout()
函数完成
from django.contrib.auth import logout
def logout_view(request):
logout(request)
实际项目开发中常会遇到以下几个问题(关于这些问题之后会详细讨论):
- 由于默认的user通常在实际开发中并不能满足我们的需求,我们通常会继承User表进行拓展以及拓展之后用户创建时需注意密码明文等问题。
- 现实中 由于session的一些缺点所以一般项目中会采用基于token的鉴权机制。
- 服务器来说,必须存储所有在线用户的session,那么这就占用了很大的资源(cpu,内存),严重影响服务器的性能.
- 扩展服务器做集群,但是同时也出现了分布式session的问题
- django 自带的权限机制无法满足项目需求 会拓展权限设置
session机制原理图:
token机制原理图:
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: