讲权限模块的设计,其实没什么太大的意义,园子里面很多高人已经写过了。前段时间自己写了一个权限模块,现在跟大家分享一下做法。
讲我的做法之前,先要说说比较通用的权限模块是如何设计的,通常是一张用户表,角色表,用户与角色关联表,功能表,角色与功能关联表,模块表。
如上设计之后,当要判断一个用户是否具有某个权限的时候先要从用户与角色关联表出发,找到当前用户所属的角色,然后再去角色功能关联表里面查找用户所属角色所具有的功能点。查找出来的用户具有功能点是一个集合,还要把当前的功能点与集合里面的所有功能点比较,如果在集合里面找到了功能点,就证明此用户具备该功能点的权限,否则就证明该用户不具备此功能点的权限。
以上做法看似繁琐,但是大部分的操作都是在用户登陆的时候就把其对应的功能点集合取出,放入Session中,那么以后判断用户是否具备某个功能点的时候只需要把功能点与Session当中的功能点集合遍历比较即可。虽然极大的避免了查库,但是还有没有一种更好的做法能取代这种功能点遍历查找,让权限的判断与集合完全无关呢?
我们先举个例子,这里用二进制的方式来表示:
假如有如下功能点以及对应的二进制码
增加——0001
删除——0010
修改——0100
查找——1000
如上定义之后,我们假设一个用户A具有增加以及删除的权限,那么我们把增加以及删除操作的二进制码进行按位或操作:0001 | 0010 = 0011
我们把0011赋给用户A,那么当我们要判断此用户是否具备增加操作的时候,只需要把增加操作的二进制码与赋给用户A的二进制码进行按位与操作:0001 & 0011 = 0001
你是否已经看出点端倪了,只要计算的结果等于要判断的功能点的二进制码,就证明用户A具有该功能点的权限了。这样的话,判断某个用户是否具备某个功能点的权限的时候只需要把用户的二进制码与功能点的二进制码进行按位与操作即可。每次判断都非常简单。
下面放出我的设计:
从上图可以看到模块表与功能表有关联,但是功能点与角色表不再有关联,因为当创建角色之后,权值(之前所说的二进制码)就已经计算好并且加入到角色表当中,从此与后面的模块表与功能表脱节无关。用户与角色有关联,是为了用户与角色可以是多对多的关系,一个用户可以具备多个角色的权限,一个角色可以对应多个用户。
这次就先说到这里,下篇再详细说说创建角色,更新角色,创建用户等更多具体操作如何实现。