Home > php教程 > php手册 > 权限设计及算法(PHPE)

权限设计及算法(PHPE)

WBOY
Release: 2016-06-21 09:06:44
Original
1356 people have browsed it

设计|算法

权限设计

大概有这几种模式:
用户+组+角色+权限
用户+组+权限
用户+角色+权限
用户+权限


最近看了别人的设计方法,大多以“整数”来表示权限值,如添加、浏览、删除和修改,分别用1、2、4、8这几个整数来代替,不过,各人的做法有所不同,举例如下:

1.用2的n次幂组成权限值的集合,如1、2、4、8、16...,某用户的权限值为其子集中的整数之和,如 7=1+2+4,5=1+4。如果要从数据库检索包含某几种权限的用户,则先把这几种权限值相加,假设和为k,然后select * from table where 1 and 用户权限值 = 'k';如果要判断某用户有哪些权限,则取出其权限值k,分别用k&1,K&2,K&4,k&16...,如果为真,则表示有值等于“&”右边整数的权限,例如,如果k&4为真,则此用户有权限表中值等于4的权限;

2.用质数2、3、5、7、11...组成权限集合,某用户的权限为其子集中各整数的乘积,如 210 = 2*3*5*7,我觉得这种方法很有趣,难点在于如何分解质因数;但我有些不认同原作者的提法,他认为权限之间可能存在包含关系,如某用户有删除权限,则其一定有浏览权限,要不然就没法删除,事实确实是这样,不过我认为这样太复杂了,容易出错,我觉得权限最好是“原子”的,互不干扰,也就是说某用户有删除权限而没浏览权限则其无法进行删除操作,因为他看不到东西,解决这个矛盾的关键是在给用户赋权时,把浏览权限也赋给他;

3.不用整数,而是用“向量表”方法(也许我说的不一定对),把所有可能的权限按一定的顺序排列,如添加、浏览、修改、删除...,用户的权限值为固定100位长度的字符串,如100010100001....01,从左起每一位对应一种操作权限,如果有这种权限,则此位的值为1,反之,则为0,作者之所以把用户权限值固定为100位,我想是考虑到升级问题,但我认为这还不够科学,我认为用户的权限值长度应小于权限个数,举例如下:
权限排列表:添加、浏览、修改、删除,用户A有添加和浏览的的权限,则其权限值为11,用户B有浏览和修改的权限则其权限值为011,用户C有浏览和删除的权限则其权限值为0101,这样设计的好处为:当权限表中增加别的权限时,不会影响用户表或角色表;

4.我曾经的做法,在后台管理中把权限分为两大类:栏目权限和操作权限,每个栏目对应一个目录,操作权限细分为浏览、添加、修改和删除,用户进入系统后首先判断有没有栏目权限,然后判断有没有操作权限,判断栏目权限相对简单一些,首先获取访问页面的路径path,然后分解出目录,对应用户拥有的目录权限,如果此目录包含在用户有权管理的目录数组中(从数据库取出),则其有进入此目录的权限,否则,没有,然而,在判断操作权限好象有些麻烦,但突然想到添加、浏览、修改和删除与我的文件命名规则是基本是对应的,但有点不同的是,我把添加和删除的功能合并在一个文件中了,例如文件名为proAddEdit.php,幸好意识到修改文件时多了个传递参数id,于是,我用正则解决了这个问题,今天看来,这种方法似乎过时了,因为不适应面向对象的思想和用框架体系来开发系统!

以上是个人粗浅的认识和描述,若有错误,请各位指正,希望高人给些意见! 

Posted by: trooman 2005-12-28 16:02
咋个这么冷清,一个发表点意见的都没有? 

Posted by: axgle 2005-12-28 16:05
已收藏。 

Posted by: Donyad 2005-12-28 16:41
1 2 3 的思想是相同的,只是实现上的手法不同而已
而3后半部分楼主的例子,恕偶愚笨,看不懂

3的做法是很C的,driver级别或者系统级别的程序很常用
比如*nix下的文件权限0755 0777之类

方法1 跟 方法3 原型是一模一样的,就是二进制位,方法3 是对这个的一个字符串模拟
二进制 十进制
100 4
+ 1 1
------------
101 5

用相互独立的位来标志权限,就是为了原子性,素数同样具有这个特性
所以派生出2的做法,而分解质因数,我并不认为这个会是一个问题,因为三种方法都需要去检查所需要的权限
既然是检查,除一下所需要的质数即可

而3里面所说的要变长的问题
1和2正好在概念上回避了这个问题
实际上,在C里面用二进制,有个对齐的问题,就是要8位8位的申请,8位8位的用,无所谓太长了浪费
只是象方法3这样用字符串来模拟二进制时会有浪费
而方法1 2在真正保存时,也是保存成一个int,也是一个申请过来就那么多位的二进制空间,无所谓浪费

扩展和弹性上,方法1和方法2是没有影响的
对方法3来说是个问题,那是因为方法3模拟得不好... 方法3感觉有猪鼻子插葱之嫌

--------------

敲code多了,文字表达能力可能不行了,偶说不对的或说不清的地方欢迎大家拍砖,3q
 

Posted by: lihun21 2005-12-28 19:27
做个记号先
学习一下
现在还没有用到这么深的权限系统
我现在只有三种权限的用户,所以还没有考虑那么多
超级管理员->普通管理员->普通用户
我想,我用的是这种模式
用户+权限 

Posted by: wwccss 2005-12-28 20:06
楼主的文章不错。Donyad兄分析的也很有水平。  

Posted by: cozo 2005-12-28 20:10
这种东西只要一种方法就可以了。
我就只使用第一种。 

Posted by: bitQ 2005-12-28 21:47
这个方法我有看到过~~~


用二进制表示权限,不会互相影响,期待做个涉及到这个的项目

高手就是高手~~` 

Posted by: BinzyWu 2005-12-28 22:01
具体怎么标记权限 这个较无所谓
一般的系统
RBAC是已经够用的.

一般Access Controller有3种
user based
group based
role based

RBAC有成熟的理论基础, 你可以搜索以下, 能搜到很多论文.

但如果不是一般的应用系统, 那么权限系统可能设计需要较为特别. 这里只有普遍理论, 未必有普遍方法.

Posted by: terpomo 2005-12-29 00:31
学习了 

Posted by: bleakwind 2005-12-29 01:14
我比较落后,我是将每个人的权限组成的数组序列化放入数据库。。。
每次载入页面初始化出来。。。 

Posted by: nameless 2005-12-29 08:51
见过一个用方法3做的权限判断,操作很方便,也很灵活

栏目权限用的直接把栏目标识用界定符分隔连接,操作时判断有没有这个标识,简单,对栏目数过多且操作员过多的时候这个数据库效率应该不高(如果操作员能超过 10W 的话),呵呵 

Posted by: trooman 2005-12-29 11:18
QUOTE (nameless @ 2005-12-29 08:51)
见过一个用方法3做的权限判断,操作很方便,也很灵活

栏目权限用的直接把栏目标识用界定符分隔连接,操作时判断有没有这个标识,简单,对栏目数过多且操作员过多的时候这个数据库效率应该不高(如果操作员能超过 10W 的话),呵呵 

是的,我也认为方法3不会比二进制的效率差,在具体使用时可以用like,str_replace等,还可以模拟二进制。

那种所谓的“栏目”权限管理,现在已经过时了,但思想还是可以沿用的,如“对应栏目”改成“对应模块”,但实现方式已经截然不同了! 

Posted by: sean.zhuo 2005-12-29 13:51
哪位大哥能給我講解一下"角色"這個概念嗎?不懂什麽叫角色. 

Posted by: KnightE 2005-12-29 14:50
1和3,本质还是一样的吧。
1有个好处,节省空间。LZ提到开100个权限用来升级。不过我遇到过一个超过100个权限类别的系统,而且用户树较多。所以后来压成了16进制存储(原来还是一样),就类似1的处理方法了。
不过3最大的好处应该在于直观(其实如果权限项很多的话,也不直观了,呵呵)。

个人认为“权限储存和判断的方法”其实还不是“权限设计”的重点和难点。我们还需要考虑其他东西。比如权限的设计结构(RBAC/GBAC/UBAC)的选择,比如权限在应用系统中的使用……

我GBAC(基于组的权限控制)用的比较多。一般的逻辑是:

组成树型结构,用户跟组结点

判断权限,从组根目录开始往用户所在组进行遍历。起始权限为“禁止”

遍历时,子组权限覆盖起始权限,直至用户。

最后用户权限覆盖起始权限。得到最终权限码。


虽然貌似有些繁杂,不过较灵活些。


其次谈谈权限的使用。通常的做法(至少我是这么做的),即在“所需”时,根据以上逻辑判断某用户相对某权限“是否通过”,例如(乱写的,只是想表示是在需要是进行判断):
CODE 

// when someone posts a new topic
if ($access_controller->check($user, 'post'))
{
   // access passed
   $user->post($content);
}
else
{
   // access denied
   $sys->accessDenied();
}
 

而我一直很想尝试的,是这样一种权限使用方法:即在$user实例出来时,已经装配好他拥有的权限(check once, run anywhere),例如:
CODE 

class User
{
   var $sid;
   var $name;
   var $passwd;
   var $email;
   // ...

   function __call()
   {
       // it must be a ACCESS DENIED process here
       die('no permission');
   }

   // maybe no other methods here...
}

// we need overload the User class in PHP4
// for the __call magic method
overload('User');
$user = new User();

// we need a AccessInject method to inject accesses into user object
$access_controller->access_inject($user)
// then, the user object includes its access methods...

// ok, we use the user's method directly
$user->post($content);
// if the user object includes the post method, it has the right permission...
 

随便写了点,没有很仔细考虑结构和命名,希望能表达清楚我的意思。
抛砖引玉…… 

Posted by: LuciferStar 2005-12-29 17:40
做过一个表单,用法1和3保存多选的表单数据。 

Posted by: james.liu 2006-01-05 17:10
如果是面向对象的,,倾向于小K的想法

用户登陆时,,如果用户名,密码,什么都对的,允许他登陆时,,实例化用户信息,包括权限 

Posted by: gudai 2006-01-11 16:06
权限设计。头疼的问题。 


         来源:http://club.phpe.net/index.php?act=Print&client=printer&f=2&t=11828

 



Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template