1. Django内置权限管理
1.1 权限分类
- Permission
用来定义用户User A对任务Task的权限。 - User
如果User A 对Model B有权限,那么User A 对Mode B中的全部实例都有相应权限。User对象的user_permission
字段用于管理用户的权限。使用assign_perm
给User分配权限。 - Group
如果Group C 对Model B有权限,那么属于Group C的全部User对Model B 都具有相应权限。
1.2 配置和实现
- Permission
Django定义每个model后,默认都会添加该model的add, change和delete三个permission,自定义的permission可以在定义model时手动添加:
|
|
每个permission都是django.contrib.auth.Permission类型的实例,该类型包含三个字段name, codename 和 content_type
,其中 content_type
反映了 permission 属于哪个 model,codename 如上面的 view_task
,代码逻辑中检查权限时要用, name 是 permission 的描述,将permission 打印到屏幕或页面时默认显示的就是 name。
在 model 中创建自定义权限,从系统开发的角度,可理解为创建系统的内置权限,如果需求中涉及到用户使用系统时创建自定义权限,则要通过下面方法:
|
|
- User和Group
django的内置权限认证被绑定在 django.contrib.auth中,而auth中的Permission模型又依赖于contenttypes。
|
|
|
|
就会在数据库中,建立如下几个表:
auth_group
auth_group_permissions
auth_permission
auth_user
auth_user_groups
auth_user_user_permissions
从表名上可以看到,auth_user
有两个外部对应关系,groups 和 user_permissions
。
|
|
上面的命令,能够让解释器加载Django项目中的settings文件,进入可以对项目中对象直接操作的模式。
|
|
每个对象的groups和user_permissions都有三个用于修改权限的方法。
A.groups.[add|remove|clear()]
A.user_permissions.[add|remove|clear()]
1.3 使用
通常使用有两种方法,
- 在View函数中通过调用has_perm()函数来检测。
A/Group.has_perm(‘applabel.task’) 用于检查用户/组的权限。另外,A.get_all_permissions()列出用户的所有权限,A.get_group_permissions()列出用户所属组的权限。 - 在View函数前使用装饰器。
@permission_required(‘applabel.task’)
2. Django-guardian
以通常的多人博客系统为例,每篇博文就是一个对象。上述的Django内置权限控制方式,达不到对象级的控制能力。Django中没有提供对象级别的权限控制,但是在架构上留下了接口。django-guardian就是一个很流行的对象级权限控制组件。Object Permission是一种对象颗粒度上的权限机制,它允许为每个具体对象授权。如果把对象b的读写权限赋予User A ,那么User A只具有对对象b的读写权限,而不能对其他同类对象进行操作。
2.1 配置
|
|
|
|
就会在数据库中,建立如下几个表:
- guardian_groupobjectpermission
- guardian_userobjectpermission
2.2 使用
- 权限的编辑
guardian.shortcuts.assign(perm, user_or_group, obj=None)
添加权限guardian.shortcuts.remove_perm(perm,user_or_group=None, obj=None)
删除权限guardian.shortcuts.get_perms(user_or_group,obj)
获取全部权限
- perm,这个参数是一个字符串,代表一个许可,格式必须为
app.perm_codename
或者perm_codename
。但是如果第三个参数是None,则必须为app.perm_codename
格式。因此建议还是统一使用app.perm_codename
格式。注意app并不是app的全路径,而是最后一级的模块名。这一点和INSTALL_APP
中的 app 全路径不同,如果你的 app module 不只一级的话,这地方一定要注意。 user_or_group
,这个参数是一个User或者Group类型的对象。- obj,这个参数就是相关的对象了。改参数是可省略的,如果省略则赋予Model权限。
- 权限的检测
user.has_perm('app.view_task')
#检测权限ObjectPermissionChecker(request.user).has_perm('app.view_task', task)
guardian.decorators.permission_required()