前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django-guardian实现对象级别的权限控制

Django-guardian实现对象级别的权限控制

作者头像
菲宇
发布2019-06-12 18:09:30
3.2K0
发布2019-06-12 18:09:30
举报
文章被收录于专栏:菲宇菲宇

概述

django-guardian是为Django提供额外的基于对象权限的身份验证后端。

特征

  • Django的对象全新啊
  • 匿名用户的支持
  • 高级API
  • 经过严密测试
  • Django admin的整合
  • 装饰器

安装

要求Django1.7或更高版本

代码语言:javascript
复制
pip install django-guardian

代码语言:javascript
复制
easy_install django-guardian

配置

安装完成后,我们可以将django-guardian加入到我们的项目。首先在settings里将guardian加入到INSTALLED_APPS

代码语言:javascript
复制
INSTALLED_APPS = ( 
    # ... 
    'guardian',
)

然后加入到身份验证后端AUTHENTICATION_BACKENDS

代码语言:javascript
复制
AUTHENTICATION_BACKENDS = ( 
    'django.contrib.auth.backends.ModelBackend', # 这是Django默认的
    'guardian.backends.ObjectPermissionBackend', # 这是guardian的
) 

注意: 一旦我们将django-guardian配置进我们的项目,当我们调用migrate命令将会创建一个匿名用户的实例(名为AnonymousUser )。 guardian的匿名用户与Django的匿名用户不同。Django匿名用户在数据库中没有条目,但是Guardian匿名用户有。这意味着以下代码将返回意外的结果

额外设置

GUARDIAN_RAISE_403

如果GUARDIAN_RAISE_403设置为True,guardian将会抛出django.core.exceptions.PermissionDenied异常,而不是返回一个空的django.http.HttpResponseForbidden

GUARDIAN_RENDER_403GUARDIAN_RAISE_403不能同时设置为True。否则将抛出django.core.exceptions.ImproperlyConfigured异常

GUARDIAN_RENDER_403

如果GUARDIAN_RENDER_403设置为True,将会尝试渲染403响应,而不是返回空的django.http.HttpResponseForbidden。模板文件将通过GUARDIAN_TEMPLATE_403来设置。

ANONYMOUS_USER_NAME

用来设置匿名用户的用户名,默认为AnonymousUser

GUARDIAN_GET_INIT_ANONYMOUS_USER

Guardian支持匿名用户的对象级权限,但是在我们的项目中,我们使用自定义用户模型,默认功能可能会失败。这可能导致guardian每次migrate之后尝试创建匿名用户的问题。将使用此设置指向的功能来获取要创建的对象。一旦获取,save方法将在该实例上被调用。

默认值为guardian.ctypes.get_default_content_type

GUARDIAN_GET_CONTENT_TYPE

Guardian允许应用程序提供自定义函数以从对象和模型中检索内容类型。当类或类层次结构以ContentType非标准方式使用框架时,这是有用的。大多数应用程序不必更改此设置。

例如,当使用django-polymorphic适用于所有子模型的基本模型上的权限时,这是有用的。在这种情况下,自定义函数将返回ContentType多态模型的基类和ContentType非多态类的常规模型。 默认为guardian.ctypes.get_default_content_type

事例项目

准备模型和自定义权限

假设我们有以下模型

代码语言:javascript
复制
from django.db import models
from django.contrib.auth.models import User
# Create your models here.


class Task(models.Model):
    summary = models.CharField(max_length=32)
    content = models.TextField()
    reported_by = models.ForeignKey(User)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        permissions = (
                ('view_task', 'View task'),
            )

说明:permissions使我们自定义的权限,当我们调用migrate命令的时候,view_task将会被添加到默认的权限集合中。 默认情况下Django为每个模型注册3个权限 * add_模型名 * change_模型名 * delete_模型名

分配对象权限

我们可以使用guardian.shortcuts.assign_perm()方法可以为用户/组分配对象权限

为用户分配权限

代码语言:javascript
复制
>>> from django.contrib.auth.models import User
>>> from todo.models import Task
>>> from guardian.shortcuts import assign_perm
>>> boss = User.objects.create(username="Big Boss") # 创建用户boss
>>> joe = User.objects.create(username="joe") # 创建用户joe
>>> task = Task.objects.create(summary="Some job", content="", reported_by=boss) # 创建Task对象
>>> joe.has_perm('view_task', task) # 默认用户对这个对象没有权限
False
>>> assign_perm('view_task', joe, task) # 为用户joe分配权限
<UserObjectPermission: UserObjectPermission object>
>>> joe.has_perm('view_task', task)
True

为用户组分配权限

代码语言:javascript
复制
>>> from django.contrib.auth.models import Group
>>> group = Group.objects.create(name="employees")
>>> assign_perm("change_task", group, task)
<GroupObjectPermission: GroupObjectPermission object>
>>> jack = User.objects.create(username="jack")
>>> jack.has_perm('change_task', task)
False
>>> jack.groups.add(group)
>>> jack.has_perm('change_task', task)
True

检查对象权限

标准方式

之前的例子我们已经用到了,我们可以使用用户实例的has_perm来检查是否有某种权限。

在视图中使用

除了Django提供的has_perm外,django-guardian还提供了一些常用的方法帮助我们检查对象权限

get_perms

代码语言:javascript
复制
>>> from guardian.shortcuts import get_perms
>>> 'change_task' in get_perms(joe, task)
False
>>> 'change_task' in get_perms(jack, task)
True

建议尽量使用标准has_perm方法。但是对于Group实例,它不是那么容易,get_perms解决这个问题很方便,因为它接受UserGroup实例。如果我们需要做更多的工作,我们可以使用ObjectPermissionChecker这个低级类,我们会在下一个章节讲。 也可以使用get_user_perms获得直接分配权限给用户(而不是从它的超级用户权限或组成员资格继承的权限)。同样的,get_group_perms仅返回其是通过用户组的权限。

get_objects_for_user

有时候我们需要根据特定的用户,对象的类型和提供的全新啊来获取对象列表,例如

代码语言:javascript
复制
>>> from guardian.shortcuts import get_objects_for_user
>>> get_objects_for_user('view_task', joe)
<QuerySet [<Task: Task object>]
>>> get_objects_for_user(jack, 'todo.change_task')
<QuerySet [<Task: Task object>]>
>>> get_objects_for_user(jack, 'todo.view_task')
<QuerySet []>

注意:这里的全权限前面要加app的名字(不知道什么)

ObjectPermissionChecker

guardian.core.ObjectPermissionChecker用于检查特定对象的用户/组的权限。因为他缓存结果,因此我们可以在多次检查权限的代码的一部分中使用

代码语言:javascript
复制
>>> from guardian.core import ObjectPermissionChecker
>>> cheker = ObjectPermissionChecker(joe)
>>> checker = ObjectPermissionChecker(joe)
>>> checker.has_perm('view_task', task)
True
>>> checker.has_perm('change_task', task)
False

使用装饰器

标准permission_required装饰器不允许检查对象权限。django-guardian随附两个装饰器,这可能有助于简单的对象权限检查,但请记住,在装饰视图被调用之前,这些装饰器会触发数据库——这意味着如果在视图中进行类似的查找,那么最可能的一个(或更多,取决于查找)会发生额外的数据库查询。

在模板中使用

django-guardian附带特殊模板标签guardian.templatetags.guardian_tags.get_obj_perms(),可以存储给定用户/组和实例对的对象权限。为了使用它,我们需要在模板中放置以下内容:

代码语言:javascript
复制
{% load  guardian_tags  %}

guardian.templatetags.guardian_tags.get_obj_perms(parser, token)返回给定用户或者组和对象(Model实例)的权限列表。

调用格式为

代码语言:javascript
复制
{% get_obj_perms user/group for obj as "context_var" %}

移除对象权限

删除对象权限和分配一样简单,我们使用guardian.shortcuts.remove_perm()来移除权限

代码语言:javascript
复制
>>> remove_perm("veiw_task",joe, task)
(0, {'guardian.UserObjectPermission': 0})
>>> joe.has_perm("view_task", task)
True
>>> remove_perm("view_task",joe, task)
(1, {'guardian.UserObjectPermission': 1})
>>> joe.has_perm("view_task", task)
False

Django admin集成

Django配有优秀和广泛使用的admin应用程序。它为Django应用程序提供基本的内容管理。具有访问管理面板的用户可以管理系统提供的用户,组,权限和其他数据。

django-guardian 为Django的admin提供简单的对象许可管理集成。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年04月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 特征
  • 安装
  • 配置
    • 额外设置
      • GUARDIAN_RAISE_403
      • GUARDIAN_RENDER_403
      • ANONYMOUS_USER_NAME
      • GUARDIAN_GET_INIT_ANONYMOUS_USER
      • GUARDIAN_GET_CONTENT_TYPE
  • 事例项目
    • 准备模型和自定义权限
      • 分配对象权限
        • 为用户分配权限
        • 为用户组分配权限
      • 检查对象权限
        • 标准方式
        • 在视图中使用
        • 在模板中使用
      • 移除对象权限
        • Django admin集成
        相关产品与服务
        访问管理
        访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档