V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
51Reboot
V2EX  ›  Python

[ Python 学习] Django 权限控制

  •  
  •   51Reboot · 2017-09-07 09:58:37 +08:00 · 5631 次点击
    这是一个创建于 2616 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本文为大家讲解 Django 框架里自带的权限模型,从理论到实战演练,带领大家了解 Django 里权限是怎么一回事。


    一、主要内容

    1 什么是权限管理?

    2 Web 权限

    3 Django 权限机制

    4 Django 的权限项

    5 权限应用

    Permission(一)

    Permission(二)

    User Permission 管理(一)

    User Permission 管理(二)

    Group Permission 管理

    权限验证(一)

    权限验证(二)

    权限验证(三)

    权限验证(四)


    二、什么是权限管理

    1 权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源
    2 权限管理好比如钥匙,有了钥匙就能把门打开,但是权限设置是有级别之分的,假如这个系统有多个权限级别就如一间屋有多个门,想要把所有门都打开您必须要取得所有的钥匙,就如系统一样。

    三、Web 权限

    在 Web 里权限管理是 Web 应用项目中比较关键的环节,因为浏览器是每一台计算机都已具备的,如果不建立权限管理系统,那么一个“非法用户”可以轻而易举通过浏览器访问 Web 应用项目中的所有功能。因此需要权限管理系统进行权限检测,让经过授权的用户可以正常合法的使用已授权的功能,而对那些未授权的非法用户拒之门外。 一个好的权限管理系统应该对每一类或每一个用户,分配不同的系统操作权限,并应具有扩展性,也就是它可以加入到任何一个带有权限管理的 Web 应用项目中,就像构件一样可以被重复使用。 同时,还要提醒开发者,开发一个 Web 应用项目时,应尽可能的将整个系统细化,分解为若干个子模块,最后组合成一个完整的应用。也只有这样,才容易实现为每一类或每一个用户分配不同的操作权限。

    四、Django 权限机制

    1 Django 权限机制能够约束用户行为,控制页面的显示内容,也能使 API 更加安全和灵活;用好权限机制,能让系统更加强大和健壮
    2 Django 用 user, group 和 permission 完成了权限机制,这个权限机制是将属于 model 的某个 permission 赋予 user 或 group,可以理解为全局的权限,即如果用户 A 对数据模型( model ) B 有可写权限,那么 A 能修改 model B 的所有实例( objects )。group 的权限也是如此,如果为 group C 赋予 model B 的可写权限,则隶属于 group C 的所有用户,都可以修改 model B 的所有实例。

    五、Django 的权限项

    1 Django 用 permission 对象存储权限项,每个 model 默认都有三个 permission,即 add model, change model 和 delete model
    2 permission 总是与 model 对应的,如果一个 object 不是 model 的实例,我们无法为它创建 /分配权限

    六、权限应用

    1 Permission
    2 User Permission
    3 Group Permission
    4 权限检查

    ◆ Permission(一)
    Django 定义每个 model 后,默认都会添加该 model 的 add, change 和 delete 三个 permission,自定义的 permission 可以在我们定义 model 时手动添加

    class Server(models.Model):
    ...
    class Meta:
    permissions = (
    ("view_server", "can view server"),
    ("change_server_status", "Can change the status of server"),
    )

    ◆ Permission(二)

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

    ◆ User Permission 管理(一)

    User 对象的 user_permission 字段管理用户的权限
    user = User.objects.get(username="rock")
    user.user_permissions = [permission_list]
    user.user_permissions.add(permission, permission, …) #增加权限
    user.user_permissions.remove(permission, permission, …) #删除权限
    user.user_permissions.clear() #清空权限
    # 注:上面的 permission 为 django.contrib.auth.Permission 类型的实例

    # 示例演示:
    In [3]: from django.contrib.auth.models import User #导入用户模块
    In [6]: user = User.objects.get(username="nick") #获取用户对象
    In [7]: user.user_permissions.all() # 查看用户权限
    Out[7]: []
    In [8]: from django.contrib.auth.models import Permission #导入权限模块
    In [10]: Permission.objects.get(pk=43) #获取权限信息
    Out[10]: <Permission: dashboard | server | 访问服务器信息>
    In [11]: Permission.objects.filter(pk=43) #获取权限信息(以列表形式输出)
    Out[11]: [<Permission: dashboard | server | 访问服务器信息>]
    In [12]: user.user_permissions = Permission.objects.filter(pk=43) #赋予用户权限(赋予权限不需要保存)
    In [13]: user.user_permissions.all() #查看用户当前权限
    Out[13]: [<Permission: dashboard | server | 访问服务器信息>]
    In [18]: user.user_permissions.add(Permission.objects.get(pk=43)) #add 添加权限(必须是一个 Permission 实例,否则报错)
    In [40]: user.user_permissions.all()
    Out[40]: [<Permission: dashboard | department | Can change department>, <Permission: dashboard | server | 访问服务器信息>]
    In [41]: user.user_permissions.remove(Permission.objects.get(pk=43)) #remove 移除权限(必须是一个 Permission 实例,否则报错)
    In [42]: user.user_permissions.all()
    Out[42]: [<Permission: dashboard | department | Can change department>]

    ◆ User Permission 管理(二)

    检查用户权限用 has_perm() 方法:
    myuser.has_perm(’ dashboard.view_server')
    has_perm() 方法的参数,即 permission 的 codename,但传递参数时需要加上 model 所属 app 的前缀,无论 permission 赋予 user 还是 group,has_perm()方法均适用

    列出用户的所有权限
    user.get_all_permissions()
    列出用户所属 group 的权限
    user.get_group_permissions()

    ◆ Group Permission 管理

    group permission 管理逻辑与 user permission 管理一致,group 中使用 permissions 字段做权限管理:
    group.permissions = [permission_list]
    group.permissions.add(permission, permission, …)
    group.permissions.remove(permission, permission, …)
    group.permissions.clear()

    ◆ 权限验证(一)

    在视图中验证权限—— permission_required
    当业务逻辑中涉及到权限检查时,decorator 能够分离权限验证和核心的业务逻辑,使代码更简洁,逻辑更清晰。permission 的 decorator 为 permission_required
    from django.contrib.auth.decorators import permission_required
    @permission_required(’ dashboard.view_server')
    def my_view(request):
    ...

    ◆ 权限验证(二)

    在类视图中验证
    from django.utils.decorators import method_decorator
    from django.contrib.auth.decorators import login_required, permission_required
    class ServerView(TemplateView):
    @method_decorator(login_required)
    @method_decorator(permission_required(“ dashboard.view_server ”)
    def get(self, request, *args, **kwargs):
    ……

    ◆ 权限验证(三)

    views 中验证
    if not request.user.has_perm(’ dashboard.view_server')
    return HttpResponse('Forbidden')

    ◆ 权限验证(四)

    Template 中的权限检查
    {% if perms.dashboard.view_server %}
    有权限
    {% endif %}

    ◆ 扩展阅读:

    使用 Django 认证系统: http://python.usyiyi.cn/translate/django_182/topics/auth/default.html

    原文阅读链接:
    http://mp.weixin.qq.com/s/DOLrxpcaGzTq6CPpkYjr5g
    6 条回复    2020-04-18 17:00:29 +08:00
    yinzishao17
        1
    yinzishao17  
       2017-09-12 20:56:33 +08:00
    我想问下,如果对业务操作进行权限管理,这个 django 应该怎么做?例如,我想控制一些信息对不同的组显示不同。这个并没有对应的 model。但我又不想写死在代码里面。因为很多场景会用到类似的处理
    51Reboot
        2
    51Reboot  
    OP
       2017-09-13 10:35:35 +08:00
    @yinzishao17 1 首先需要前端控制,通过前端代码控制,没权限不显示功能。
    2 无权限发现没有 idc 管理按钮
    51Reboot
        3
    51Reboot  
    OP
       2017-09-13 10:46:23 +08:00
    @yinzishao17
    权限控制分多个方面,1. 前端:首先需要前端控制,通过前端代码作 if 判断,没权限不显示功能。
    2. 后端:需要通过用户组获取对应的不同权限。
    如下:In [1]: from django.contrib.auth.models import Permission, Group

    In [2]: g = Group.objects.get(name="devops")
    In [17]: p = Permission.objects.get(pk=26)

    In [18]: g.permissions.add(p) #添加权限序号为 26 的权限给用户组 devops#
    通过前后端验证才能实现权限的控制
    yinzishao17
        4
    yinzishao17  
       2017-09-14 17:46:06 +08:00
    @51Reboot 感谢回答。其实我的疑问是,权限序号为 26 的权限,这个 permission 应该有对应的 content_type。而 content_type 则需要关联到具体的模型。但我这个权限的含义是找不到对应的模型的。我现在的思路是自己创建一个不存在的模型,content_type = ContentType.objects.create(app_label='action', model='acl')。
    hsluoyz
        5
    hsluoyz  
       2019-01-26 09:02:28 +08:00
    @51Reboot @yinzishao17 可以试下最近新推出的 Python 权限管理方案 PyCasbin: https://github.com/casbin/pycasbin
    kayseen
        6
    kayseen  
       2020-04-18 17:00:29 +08:00
    @yinzishao17
    请问这个问题最终解决了吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2704 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:24 · PVG 23:24 · LAX 07:24 · JFK 10:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.