Django的权限控制

2023年 1月 4日 76.9k 0

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时手动添加:

    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)
    
  • 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','[email protected]','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 使用

  • 权限的编辑
  • 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()

    3. 参考资料

    • http://python.usyiyi.cn/django/topics/auth/default.html
    • http://www.jianshu.com/p/01126437e8a4
    • https://django-guardian.readthedocs.io/en/stable/overview.html

    相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    那些年在 Terraform 上吃到的糖和踩过的坑
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更

    发布评论