惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
V
V2EX
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
A
About on SuperTechFans
博客园_首页
L
LangChain Blog
量子位
雷峰网
雷峰网
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Jina AI
Jina AI
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19)
Django的权限控制
2017-01-22 · via 陈少文的网站

Please enable Javascript to view the contents

1. Django内置权限管理

1.1 权限分类

  1. Permission
    用来定义用户User A对任务Task的权限。
  2. User
    如果User A 对Model B有权限,那么User A 对Mode B中的全部实例都有相应权限。User对象的user_permission 字段用于管理用户的权限。使用 assign_perm 给User分配权限。
  3. Group
    如果Group C 对Model B有权限,那么属于Group C的全部User对Model B 都具有相应权限。

1.2 配置和实现

  1. Permission

Django定义每个model后,默认都会添加该model的add, change和delete三个permission,自定义的permission可以在定义model时手动添加:

1
2
3
4
5
6
7
8
class Task(models.Model):
    ...
    class Meta:
        permissions = (
            ("view_task", "Can see available tasks"),
            ("change_task_status", "Can change the status of tasks"),
            ("close_task", "Can remove a task by setting its status as closed"),
        )

每个permission都是django.contrib.auth.Permission类型的实例,该类型包含三个字段name, codename 和 content_type,其中 content_type 反映了 permission 属于哪个 model,codename 如上面的 view_task,代码逻辑中检查权限时要用, name 是 permission 的描述,将permission 打印到屏幕或页面时默认显示的就是 name。

在 model 中创建自定义权限,从系统开发的角度,可理解为创建系统的内置权限,如果需求中涉及到用户使用系统时创建自定义权限,则要通过下面方法:

1
2
3
4
5
6
from myapp.models import Post
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(Post)
permission = Permission.objects.create(codename='can_publish', name='Can Publish Posts', content_type=content_type)
  1. User和Group

django的内置权限认证被绑定在 django.contrib.auth中,而auth中的Permission模型又依赖于contenttypes。

1
2
3
4
INSTALLED_APPS = (
    'django.contrib.auth'
    'django.contrib.contenttypes'
)
1
manage.py syncdb

就会在数据库中,建立如下几个表:

  • auth_group
  • auth_group_permissions
  • auth_permission
  • auth_user
  • auth_user_groups
  • auth_user_user_permissions

从表名上可以看到,auth_user 有两个外部对应关系,groups 和 user_permissions

1
manage.py  shell

上面的命令,能够让解释器加载Django项目中的settings文件,进入可以对项目中对象直接操作的模式。

1
2
3
4
>>> from django.contrib.auth.models import User
>>> A  = User.objects.create_user('name','nameg@email.com','password')
>>> A.groups = [group_list]
>>> A.user_permissions = [permission_list]

每个对象的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 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

pip install django-guardian

INSTALLED_APPS = (
    'guardian',
)

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend', # this is default
    'guardian.backends.ObjectPermissionBackend',
]
#如果要支持匿名用户AnoymousUser的Object级别的权限控制,要在settings中加入
#匿名用户权限控制
ANONYMOUS_USER_ID = -1
1
python manage syncdb

就会在数据库中,建立如下几个表:

  • guardian_groupobjectpermission
  • guardian_userobjectpermission

2.2 使用

  1. 权限的编辑

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权限。
  1. 权限的检测
  • user.has_perm('app.view_task') #检测权限
  • ObjectPermissionChecker(request.user).has_perm('app.view_task', task)
  • guardian.decorators.permission_required()

3. 参考资料


微信公众号

作者

微信公众号