Discuz教程网

[二次开发] 基于discuz的权限表进行分析

[复制链接]
authicon dly 发表于 2014-1-14 08:33:20 | 显示全部楼层 |阅读模式
disucz后台的权限进行分析如下:
-------------------------------------------------
用户权限的增删修改删除操作                                                
-------------------------------------------------
用户权限分配
一:用户权限组表 pre_common_admincp_group
cpgroupid        cpgroupname
1                        门户管理
2                        群组管理
二:组对应的权限:pre_common_admincp_perm        
cpgroupid        perm(权限符)
1                        block
2                        arcitle         
2                        update
2                        title
2                        write        
三:用户对应有哪些权限pre_common_admincp_member
uid                        cpgroupid                customperm(其他权限,其中这个是序列化存入的)
1                        2                                
2                        2                                delete
3                        1                                update                                

//如何查询用户的权限??(查询某个特定的用户的权限)
根据表 pre_common_admincp_member表中的cpgroupid从表pre_common_admincp_perm中把权限查询出来
然后在把customperm这个字段的权限结合起来,就是某个用户的权限。。

用户uid是1的权限有 block arcitle update title write
----------------------------------------------------------------
增加权限:
我先给用户uid是1的用户增加权限 delete
游客,如果您要查看本帖隐藏内容请回复

----------------------------------------------------------------
//删除用户所具有的某个权限:
1:所要删除的权限是在表pre_common_admincp_perm中 这个很简单
首先要从表pre_common_admincp_perm中把uid=1 的字段customperm查询出来,然后删除传递的权限值,然后在存入数据库即可
2:所要删除的权限是在pre_common_admincp_perm表中,此处的删除不能把权限从pre_common_admincp_perm表中删除,如果删除会影响到
其他用户的权限。我们其实可以加一个标识比如说删除的话我们加个前缀delete_delete即可,然后在存入到表pre_common_admincp_perm里面即可。
//提取用户的权限。。
要从表pre_common_admincp_member表字段 customperm字段 和表 pre_common_admincp_perm 进行关联查询,
并且查询出来的2个数组,要进行排除前缀是:delete_的数据即可
------------------------------------------------------------
这个就是基本的思路 ok



有更好的解决办法
PHPChina的专家版在谈权限设计,苦于没有权限回帖,特发此博文谈谈简单的权限设计。讨论在这里。
  最简单的权限验证,应该是登录态的验证,如果登录,则可以怎样,没有登录,则不能怎样:
  PHPChina的专家版在谈权限设计,苦于没有权限回帖,特发此博文谈谈简单的权限设计。讨论在这里。
  最简单的权限验证,应该是登录态的验证,如果登录,则可以怎样,没有登录,则不能怎样:
1.if ($isLogin === true) {
2. //do something
3.} else {
4. //do nothing
5.}
  一般使用会话或者Cookie来保存登录态,具体实现不在此文讨论范围。一般权限都和人挂勾,首先识别你是谁,然后看你有能力做什么,然后再确认你的能力在这个地方是否可以使,一个权限验证算是基本上完成。我们围绕这几点来看权限如何去设计。
  首先要能识别操作者是何许人,我们需要一张保存操作者信息的表,也就是通常所说的用户表。简单的用户表如下:
1.CREATE TABLE user (
2. userId int(10) unsigned NOT NULL,
3. username varchar(255) NOT NULL,
4. PRIMARY KEY (userId)
5.)
  一般使用一个用户ID来标识一个唯一的用户,可以使用数字,或者直接使用用户名作为主键(如果用户名不重复)。这里我们使用userId来唯一标识一个用户。
  有了用户以后,接下来需要确认这个用户所具有的能力,也就是权限,那么首先我们需要列一下我们的系统总共需要几个权限,比如增、删、改、查等。增加一张权限表:
1.CREATE TABLE permission (
2. permissionId int(10) unsigned NOT NULL ,
3. permissionName varchar(255) NOT NULL ,
4. PRIMARY KEY (permissionId)
5.)
  同样的我们以permissionId作为主键来唯一标识一个权限,当然也可以使用permissionName来标识(如果你能确定唯一的话)。我们新增几条记录在这张表里:
1.+————–+—————-+
2.| permissionId | permissionName |
3.+————–+—————-+
4.| 1 | add |
5.| 2 | del |
6.| 3 | modify |
7.| 4 | select |
8.+————–+—————-+
  这里列举了4个权限,简单的表示我们的用户在系统里可能具有的增、删、改、查4种不同的能力。
  接下来把这些能力赋给用户,需要一张对应表来保存:
1.CREATE TABLE userPermission (
2. userId int(10) unsigned NOT NULL,
3. permissionId int(10) unsigned NOT NULL,
4. PRIMARY KEY (userId, permissionId)
5.)
  其中将userId和permissionId设置为主键,表示某个用户具有某种权限。表内容可能如下:
01.+——–+————–+
02.| userId | permissionId |
03.+——–+————–+
04.| 1 | 1 |
05.| 1 | 4 |
06.| 2 | 1 |
07.| 2 | 2 |
08.| 2 | 3 |
09.| 2 | 4 |
10.+——–+————–+
  以上权限配置表明用户1具有增、查权限,用户2具有增、删、改、查权限(嗯可以猜想用户1是个普通用户,用户2是个管理员)。
  写到这里,我发现基本的用户权限系统雏型已经完成了。这么简单?看起来好像确实就是这么简单。一个用户拥有哪些权限,那么只需要勾选相应的权限分配给这个用户。在验证权限的时候,取出用户所拥有的所有权限,然后判断是否存在该权限即可。
  实际上的权限设计要比这个复杂一些,到底复杂在哪里呢?我们接下来分析。当用户比较多而且权限数量比较多的时候,你是不是要每个用户都去勾选一堆权限呢?如何简化这个操作?OK,用户组的概念推出。所谓用户组,就是具有某些权限的一类人的集合。我们赋予用户组某些权限,然后把这个用户加到这个用户组里即可,来看看用户组长什么样子:
1.CEATE TABLE group (
2. groupId int(10) unsigned NOT NULL,
3. groupName varchar(255) NOT NULL,
4. PRIMARY KEY (groupId)
5.)
  和用户表类似,我们需要标识一个唯一的组,这里分配一个组ID作为主键来标识。内容可能如下:
1.+———+———–+
2.| groupId | groupName |
3.+———+———–+
4.| 1 | user |
5.| 2 | admin |
6.+———+———–+
  有了用户组表后,我们需要把一些权限赋给用户组,就需要一张用户组权限表:
1.CREATE TABLE groupPermission (
2. groupId int(10) unsigned NOT NULL,
3. permissionId int(10) unsigned NOT NULL,
4. PRIMARY KEY (groupId, permissionId)
5.)
  我们分配增、查权限给user组,分配增、删、改、查权限给admin组:
01.+———+————–+
02.| groupId | permissionId |
03.+———+————–+
04.| 1 | 1 |
05.| 1 | 4 |
06.| 2 | 1 |
07.| 2 | 2 |
08.| 2 | 3 |
09.| 2 | 4 |
10.+———+————–+
  用户组表和用户组所对应的权限表有了,那么要把用户分配给一个用户组,就需要一张用户和组的对应关系表:
1.CREATE TABLE userGroup (
2. userId int(10) unsigned NOT NULL,
3. groupId int(10) unsigned NOT NULL,
4. PRIMARY KEY (userId, groupId)
5.)
  把用户1赋给user组,把用户2赋给admin组,和一开始我们直接分配权限一样:
1.+——–+———+
2.| userId | groupId |
3.+——–+———+
4.| 1 | 1 |
5.| 2 | 2 |
6.+——–+———+
  很明显这里的配置信息相对比userPermission表少很多,这里只需要记录用户属于什么组就可以了,那么检测用户权限,就需要查出用户所在的组,然后再查出这个组(或者这些组)所拥有的权限,就可以得出用户所具备的权限,再进行验证即可。当然会比直接查询userPermission表绕一点点,不过相对比维护成本,这点点消耗不算什么。更何况我们其实仍然可以保存userPermission表,在分配用户组的时候,同时更新 userPermission表即可。
  这里可以看到,除了在分配用户权限方便以外,当你需要更改某类用户权限的时候,你只需要更改其所在组的权限,那么这个组下所有成员的权限也会随之更改,非常方便。
  到这里用户、用户组的权限构成基本完成。它能解决大部分问题,可是我发现它仍然有一些小的问题。比如如果某个用户只有查权限,我不得不再新增一个用户组,搞得用户组也很多,怎么办呢?如果这个用户属于普通用户组,其实可以考虑也分配普通用户组给这个用户,然后再从普通用户组里“扣掉”增权限。要达到这样的效果,怎么处理呢?
  其实很简单,我们刚才没有去掉的userPermission表派上用场,这个表存储了用户的实际单个权限,我们只需要增加一个字段标识用户是拥有这个权限,还是没有这个权限即可,这样可以解决两个问题:一是从现有用户组中扣掉某些权限,二是在现有用户组中,再给这个用户增加用户组以外的权限。来看一下userPermission表:
1.CREATE TABLE userPermission (
2. userId int(10) unsigned NOT NULL,
3. permissionId int(10) unsigned NOT NULL,
4. has enum(‘yes’,'no’) NOT NULL,
5. PRIMARY KEY (userId, permissionId)
6.)
  把用户1的增权限去掉,那么内容可能像这样:
查看源代码
打印?
01.+——–+————–+—–+
02.| userId | permissionId | has |
03.+——–+————–+—–+
04.| 1 | 1 | no |
05.| 1 | 4 | yes |
06.| 2 | 1 | yes |
07.| 2 | 2 | yes |
08.| 2 | 4 | yes |
09.| 2 | 3 | yes |
10.+——–+————–+—–+
  这个用户依然在user组里,只不过user组所拥有的2个权限(add, select),他少了个add(ID为1被标记为no)权限而已。
  嗯,这样做有解决了这个小问题,不过这个功能增强会让分配权限代码更复杂一些,不仅要给用户分配组,还可能需要操作具体权限,让他有或者让他没有相应的权限。
  OK,简单的权限设计全部完成,只不过,细心的读者,你是否意识到,还少点什么呢?没错,即使到这里,整个权限验证还少了一块很重要的部分,那就是用户拥有这些权限,那么他能在哪里使用这些权限。考虑一个例子,一个论坛版主在他所管理的论坛版块里拥有删、改帖子的权限,他在其他非他所管理的版块就没有这些权限,可能在其他论坛版块他像是一个普通用户一样,我们上面讨论的权限设计如何做到这个验证呢?那么我个人觉得,权限设计到上面已经完成了,接下去这种情况,属于业务逻辑层的验证,我们从权限系统中已经获得用户的权限,那么在具体业务逻辑中,和权限进行绑定即可,以上例子可以用一个版块用户关系表来解决这个问题:
1.CREATE TABLE userBoard (
2. userId int(10) unsigned NOT NULL,
3. boardId int(10) unsigned NOT NULL,
4. PRIMARY KEY (userId, boardId)
5.)
  标记用户拥有哪些版块的管理权限,那么在严重用户拥有管理权限的时候,还要看当前版块是否是用户管辖内的版块,最终确定用户是否有操作权限。那么我将这类和业务逻辑相关的权限分配归到用户角色里,同样可以创建一系列角色,来管理用户所管辖的范围,比如超级版主,他也是具有管理删、改权限,只不过他的权限作用于全论坛,那么普通版主就需要指定论坛,这样来区分用户组和角色组我想会使整个权限系统更加清晰。
  到这里,权限验证全部完成,以上没有具体实现代码,我相信这样已经足够了,具体的实现代码和业务逻辑由具体的应用实现吧。



上一篇:空间主页有些动态没显示删除
下一篇:如何解决Discuz设置精华帖子之后不显示的问题
authicon 287681667 发表于 2015-12-8 13:17:00 | 显示全部楼层
长点知识,长度不能少于十个字
authicon 哦哦嗯呢 发表于 2017-4-27 20:21:10 | 显示全部楼层
回复一下。。。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2024-4-26 08:21

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表