基于角色的权限系统
现在各大系统都采用的是基于角色的权限控制,这里就涉及到三个东西:用户、角色、资源(权限),在Django中就是:用户、用户组、权限。用户和角色的关系一般为多对多,角色和资源的关系也为多对多,如下图(此图来源于互联网)
这样设计有一个好处,就是在系统越来越大的时候如果给每个用户逐一赋予权限非常麻烦和繁琐,只需要给角色赋予相应的权限用户赋予他对应的角色即可,如果有新的需求只需要添加有相应权限的角色即可。
Django权限机制的实现
1、不依赖于Django中的权限模型
设计三个实体类User、Role、Resource分别对应上面提出的用户、角色、资源,User和Resource之间为多对多的关系,Role和Resource之间为多对多的关系。User中封装的是用户的信息如用户名密码等,Resource可以封装权限标识(后面再进行分析)也可以封装允许访问的URL地址。
编写装饰器对视图处理方法进行拦截
- 资源封装URL
在装饰器中获取当前访问的URL,取出当前用户(从Session中取,前题是在登录的时候需要把用户信息放去Session中去),迭代判断用户的所有角色绑定的资源中的URL,如果存在与当前访问URL相同的地址则放行,否则则跳转到无权限的页面。
弊端:如果URL发生了变动需要修改资源(权限)
- 资源封装权限标识
在装饰器标示在视图处理方法上时传入权限标识参数(如:@auth("user:add")),在装饰器中也是从Session中获取用户,迭代用户的所有角色绑定的资源中的权限标识,如果与传入装饰器中的权限标识相同则放行,否则跳转到无权限的页面。
好处:如果URL发生了变动无需修改资源(权限),Django内部的权限系统就是采用的这种方式,Java目前越来越流行的权限控制框架Shiro也是采用的这种方式
2、依赖于Django中的权限模型(部分摘抄于:http://www.jianshu.com/p/01126437e8a4)
Django用User、Group、Permission来表示上面的用户、角色、资源(权限),在Django中不管你是否使用其自带的权限控制只要你继承了他的模型类(models.Model)会默认在auth_permission表中插入三个权限信息(以Book为例,会插入如下三个权限信息:add_book、change_book、delete_book,分别代表了添加、修改、删除三个权限),如果需要更多的权限信息可以在定义实体的时候如下定义:
class Book(models.Model):
name = models.CharField()
class Meta:
permissions = (
('自定义的权限标识', '权限说明信息'),
)
每个permission都是django.contrib.auth.Permission类型的实例,该类型包含三个字段name, codename 和 content_type,其中 content_type反应了permission属于哪个model(如上就是Book),codename就是权限标识,代码逻辑中检查权限时要用, name是permission的描述显示的时候会用到。
权限检测装饰器:request.user封装了当前登录系统的用户
from django.contrib.auth.decorators import permission_required
@permission_required('应用名.权限标识')
def view(request):
....
在模版中使用:模版中使用全局变量perms存储当前用户的所有权限
{% if perms.应用名.权限标识 %}
<!-- 这里是有权限才显示的内容 -->
{% endif %}
来源:oschina
链接:https://my.oschina.net/u/2427367/blog/755544