[ Python 学习] Django 权限控制 - V2EX
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 6206 次点击
    这是一个创建于 2988 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本文为大家讲解 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.getgroup_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  
    PRO
       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     Solana     1021 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 18:48 PVG 02:48 LAX 10:48 JFK 13:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86