web2py通过@修饰符控制每个function的访问权限,假如系统有a、b、c、d 4个角色,最常用的是
1、登录后才能访问:
@auth.requires_login()
def function_two():
.....
return 'this requires login'
2、某个角色能访问
@auth.requires_membership('a')
def function_three():
.....
return 'this requires role a'
或者
@auth.requires(auth.has_membership(role='a'))
def function_three():
.....
return 'this requires role a'
如果同时要同时多个角色访问某个function怎么办呢,以上两种方法,传递的参数都只能是单个角色,不能一次传一个列表,其中一个可能的办法是这样,
@auth.requires(auth.has_membership(role='a') or auth.has_membership(role='b') )
def function_four():
.....
return 'this requires role a or b '
很明显,当有好几个角色要同时访问某个function时,需要调用好多次,而且or逻辑最后的那个角色,前面要调用N次后才能判断出来,系统开销很大;
3、解决方法
可以 改造框架的源代码,让auth.has_membership能接受 一个列表,调用一次在即可,但是有个更好的快速办法,我们让a.b.c个角色都能访问某function
@auth.requires(not set(auth.user_groups.values()).isdisjoint({'a','b','c'}))
def function_five():
.....
return 'this requires role a or b or c'
(1)auth.user_groups.values()可以一次性读取该用户的所有角色名称,
(2)通过set()方法,将其转换为“集合”数据类型,
(3)然后用集合的isdisjoint()方法,判断用户所拥有的角色,和授权可访问的角色是否有交集,有交集就返回False,
(4)有交集返回False,那我们在逻辑上 取反,最终刚好是我们需要的结果:
一个用户属于多个角色,一个funtion有需要多个角色可以访问,一次性的快速鉴权。