设计OA时,sp权限的3个小问题

#1 土蚕

以前做的小系统中已经使用到了sp网站中介绍的权限管理方式,很好用,特别是有限权限和强制权限的设计,最近在构思一个简单的学校OA,涉及到权的几个问题:
1.论坛问答中,在user表中acl_name您说可以理解成组(http://www.speedphp.com/forum.php?mod=viewthread&tid=4465),因为OA登陆的是姓名和密码,所以每个人只能属于一个组。而我们学校有个人既是部门领导,又是教师,按我的理解,是不是出现一个用户属于多个组的情况时,就新增一个组,并给予对应的权限。但是如果进入系统后,此人发送通告,如何确定他是领导身份还是教师身份呢?难道要为了这个新的组,要用if判断,分开显示不同内容吗?要是这样的人多了,程序判断上会很烦。

2.看了一些设计权限管理的帖子,一般是用户、权限、角色三者之间多对多的关系,并且还需要中间表,而sp的权限设计很简洁,我的理解:acl表相当于权限和角色的中间表,而user表则是用户到角色是一对一的关系。这样设计有什么好处?

3.随着系统中应用模块的增多,控制器和动作会越来越多,每新增一个新组和设置对应的权限,都要手工添加很多数据到acl表,有没有好的解决办法?我用scandir() 加 get_class_methods()来列出控制器名和动作,因为我把这段写在main.php控制器中,只列出了main控制器的相关动作。不知为何?
我主要想用这种方式来列出所有需要加中文名称的控制器和动作,然后用复选框给它们加上多个acl_name,这样好管理一些。





2014-12-05 00:23:39

#2 jake

1.论坛问答中,在user表中acl_name您说可以理解成组(http://www.speedphp.com/forum.php?mod=viewthread&tid=4465),因为OA登陆的是姓名和密码,所以每个人只能属于一个组。而我们学校有个人既是部门领导,又是教师,按我的理解,是不是出现一个用户属于多个组的情况时,就新增一个组,并给予对应的权限。但是如果进入系统后,此人发送通告,如何确定他是领导身份还是教师身份呢?难道要为了这个新的组,要用if判断,分开显示不同内容吗?要是这样的人多了,程序判断上会很烦。

你理解的不错,acl是组的概念。不过一个人不一定只能属于一个组。你说的情况,可以这样解决:
1. 通常来说,权限这种东西,各组的权限都是递减的。也就是类似"管理员">"普通用户">"匿名用户",所以在一般设计来说,如果一个用户是管理员又是普通用户,那么他只需要是管理员即可。虽然这个和你的系统有点不太适合,不过“如何确定他是领导身份还是教师身份呢?”这个就可以认为他是高级的权限,比如说是“领导”。
2. 相信上面的说法你应该也理解,不过可能你的系统概念不一样,所以“领导”不一定大于“教师”,那么只能按你说的情况,为这种角色新增加一个组。而组可以通过CRUD在页面上面增减的,管理成本不会增加。—— 这里只针对权限,显示是什么身份,这个要看你需求。正常来说只显示个“领导”就行了吧?
3. 还有一种做法,可以在用户表里面,增加两个权限字段(或者更多个),用户可以是两个(或者更多个)角色,这些角色按权限大小来排列,显示的时候取第一个即可。不过这个做法不灵活的地方是只能限定一个用户最多有几个权限。—— 也没有关系,一般一个用户不会有太多角色的,因为整个系统可能就几个角色而已。另外也可以把用户和角色表做成多对多,多了个中间表,但是最多权限角色的限制就不存在了——管理成本有所增加。


2.看了一些设计权限管理的帖子,一般是用户、权限、角色三者之间多对多的关系,并且还需要中间表,而sp的权限设计很简洁,我的理解:acl表相当于权限和角色的中间表,而user表则是用户到角色是一对一的关系。这样设计有什么好处?

从两个方面讲,好像手册里面也提到,就是如果某角色的用户比较少,那么用户直接==角色也是可以的,简洁来说就是这样。
用户,角色,权限这块的分开,是针对一般系统的设计。好处是可以适合大部分情况下的系统权限的需求。举两个例子:
1. 假设是一个文章系统,有管理员、文章作者、投稿作者(比文章作者少一些功能)、普通用户(只能页面上评论,进不了后台发文章)、匿名访问用户(没有登录的),那么角色就是上述5个(或者4个,匿名那个可以不设角色,除非是强制权限)。这样不管是增加用户,增加权限等,都比较方便。
2. 假设还是个文章系统,只有管理员、作者两种用户,而管理员只有一两个人,这样的情况,可以把“管理员角色”直接等同于某个用户,这样也是可以的。



3.随着系统中应用模块的增多,控制器和动作会越来越多,每新增一个新组和设置对应的权限,都要手工添加很多数据到acl表,有没有好的解决办法?我用scandir() 加 get_class_methods()来列出控制器名和动作,因为我把这段写在main.php控制器中,只列出了main控制器的相关动作。不知为何?
我主要想用这种方式来列出所有需要加中文名称的控制器和动作,然后用复选框给它们加上多个acl_name,这样好管理一些。

其实权限控制,也可以做成直接按控制器一级来区分(当前前提是各控制器的作用要分明),不一定要判断到控制器+动作。打个比方:
这里是个权限表:

角色1 | 控制器A | *
角色1 | 控制器B | index,send,login
角色2 | 控制器A | *

类似这样,判断起来是发现如果是*星号的,那么就是整个控制器都有权限了,这样就少了很多录入的工作。控制器怎么也不会太多吧。
这个判断,可以放到ACL的扩展spAclModel里面,可以看看ACL的源码,spAclModel的机制是让大家可以扩展权限判断的,写个新的类,类似spAclModel差不多的样子,然后在check里面做你的判断。

再通过配置里面(这里是原来的配置)
'ext' => array( // 扩展设置
        'spAcl' => array( // acl扩展设置
                'prompt' => array("lib_user", "acljump"),
        ),
)
加上checker(加上新的配置)
'ext' => array( // 扩展设置
        'spAcl' => array( // acl扩展设置
                'prompt' => array("lib_user", "acljump"),
                'checker' => array("你的新类", "check"),
        ),
)
这样speedphp就会执行你的权限判断函数check,而不是默认的spAclModel的check了。也不需要在其他地方做IF检查,也不影响到其他代码。


2014-12-05 09:31:07

#3 土蚕

感谢JAKE这么快速和详细的回复,看了几遍,继续讨论

问题1中学生处领导显示的内容是关于学生处的,而作为教师,还要展现所教的班级
用户表能不能这样

用户名1 | 密码1 | 学生处主任,教师
用户名2 | 密码2 | 教师
用户名3 | 密码3 | 学生

spClass("spAcl")->get();读到权限后,转为数组,最后用spClass('spAcl')->set("GBADMIN");赋值可以吗?
如果sp3不支持,还需要调整哪些地方?谢谢

2014-12-05 10:23:11

#4 jake

土蚕 发表于 2014-12-5 10:23
感谢JAKE这么快速和详细的回复,看了几遍,继续讨论

问题1中学生处领导显示的内容是关于学生处的,而作为 ...
可以的
一个字段多个逗号分隔,这是我比较喜欢的做法。多个字段会有限,但是逗号的方法就不限了。
这种方法是OK的,只是上面为了说得明白点,没讲到这个方法。

两个方法:
1. 按你说的,读到权限后再才拆开,然后再赋予权限。这是在登录的时候做的。

2. 可以在你自己的check里面,把逗号分割的值取出来,然后explode拆分,就可以判断了。

2014-12-05 10:31:14

#5 jake

补充一下:

两个方法:
1. 按你说的,读到权限后再才拆开,然后再赋予权限。这是在登录的时候做的。
2. 可以在你自己的check里面,把逗号分割的值取出来,然后explode拆分,就可以判断了。

2014-12-05 11:12:53

#6 土蚕

谢谢提示,目前基本理清了。有问题再来论坛麻烦你,:D

2014-12-05 13:11:37