2019独角兽企业重金招聘Python工程师标准>>>

By 深空, 2009-09-13 21:45:07

PHPChina的专家版在谈权限设计,苦于没有权限回帖,特发此博文谈谈简单的权限设计。讨论在这里
最简单的权限验证,应该是登录态的验证,如果登录,则可以怎样,没有登录,则不能怎样:

1
2
3
4
5
if ( $isLogin === true) {
     //do something
} else {
     //do nothing
}

一般使用会话或者Cookie来保存登录态,具体实现不在此文讨论范围。一般权限都和人挂勾,首先识别你是谁,然后看你有能力做什么,然后再确认你的能力在这个地方是否可以使,一个权限验证算是基本上完成。我们围绕这几点来看权限如何去设计。
首先要能识别操作者是何许人,我们需要一张保存操作者信息的表,也就是通常所说的用户表。简单的用户表如下:

1
2
3
4
5
CREATE TABLE user (
     userId int (10) unsigned NOT NULL ,
     username varchar (255) NOT NULL ,
     PRIMARY KEY (userId)
)

一般使用一个用户ID来标识一个唯一的用户,可以使用数字,或者直接使用用户名作为主键(如果用户名不重复)。这里我们使用userId来唯一标识一个用户。
有了用户以后,接下来需要确认这个用户所具有的能力,也就是权限,那么首先我们需要列一下我们的系统总共需要几个权限,比如增、删、改、查等。增加一张权限表:

1
2
3
4
5
CREATE TABLE permission (
     permissionId int (10) unsigned NOT NULL ,
     permissionName varchar (255) NOT NULL ,
     PRIMARY KEY (permissionId)
)

同样的我们以permissionId作为主键来唯一标识一个权限,当然也可以使用permissionName来标识(如果你能确定唯一的话)。我们新增几条记录在这张表里:

1
2
3
4
5
6
7
8
+--------------+----------------+
| permissionId | permissionName |
+--------------+----------------+
|            1 | add            |
|            2 | del            |
|            3 | modify         |
|            4 | select         |
+--------------+----------------+

这里列举了4个权限,简单的表示我们的用户在系统里可能具有的增、删、改、查4种不同的能力。
接下来把这些能力赋给用户,需要一张对应表来保存:

1
2
3
4
5
CREATE TABLE userPermission (
     userId int (10) unsigned NOT NULL ,
     permissionId int (10) unsigned NOT NULL ,
     PRIMARY KEY (userId, permissionId)
)

其中将userId和permissionId设置为主键,表示某个用户具有某种权限。表内容可能如下:

1
2
3
4
5
6
7
8
9
10
+--------+--------------+
| userId | permissionId |
+--------+--------------+
|      1 |            1 |
|      1 |            4 |
|      2 |            1 |
|      2 |            2 |
|      2 |            3 |
|      2 |            4 |
+--------+--------------+

以上权限配置表明用户1具有增、查权限,用户2具有增、删、改、查权限(嗯可以猜想用户1是个普通用户,用户2是个管理员)。
写到这里,我发现基本的用户权限系统雏型已经完成了。这么简单?看起来好像确实就是这么简单。一个用户拥有哪些权限,那么只需要勾选相应的权限分配给这个用户。在验证权限的时候,取出用户所拥有的所有权限,然后判断是否存在该权限即可。
实际上的权限设计要比这个复杂一些,到底复杂在哪里呢?我们接下来分析。当用户比较多而且权限数量比较多的时候,你是不是要每个用户都去勾选一堆权限呢?如何简化这个操作?OK,用户组的概念推出。所谓用户组,就是具有某些权限的一类人的集合。我们赋予用户组某些权限,然后把这个用户加到这个用户组里即可,来看看用户组长什么样子:

1
2
3
4
5
CREATE TABLE group (
     groupId int (10) unsigned NOT NULL ,
     groupName varchar (255) NOT NULL ,
     PRIMARY KEY (groupId)
)

和用户表类似,我们需要标识一个唯一的组,这里分配一个组ID作为主键来标识。内容可能如下:

1
2
3
4
5
6
+---------+-----------+
| groupId | groupName |
+---------+-----------+
|       1 | user      |
|       2 | admin     |
+---------+-----------+

有了用户组表后,我们需要把一些权限赋给用户组,就需要一张用户组权限表:

1
2
3
4
5
CREATE TABLE groupPermission (
     groupId int (10) unsigned NOT NULL ,
     permissionId int (10) unsigned NOT NULL ,
     PRIMARY KEY (groupId, permissionId)
)

我们分配增、查权限给user组,分配增、删、改、查权限给admin组:

1
2
3
4
5
6
7
8
9
10
+---------+--------------+
| groupId | permissionId |
+---------+--------------+
|       1 |            1 |
|       1 |            4 |
|       2 |            1 |
|       2 |            2 |
|       2 |            3 |
|       2 |            4 |
+---------+--------------+

用户组表和用户组所对应的权限表有了,那么要把用户分配给一个用户组,就需要一张用户和组的对应关系表:

1
2
3
4
5
CREATE TABLE userGroup (
     userId int (10) unsigned NOT NULL ,
     groupId int (10) unsigned NOT NULL ,
     PRIMARY KEY (userId, groupId)
)

把用户1赋给user组,把用户2赋给admin组,和一开始我们直接分配权限一样:

1
2
3
4
5
6
+--------+---------+
| userId | groupId |
+--------+---------+
|      1 |       1 |
|      2 |       2 |
+--------+---------+

很明显这里的配置信息相对比userPermission表少很多,这里只需要记录用户属于什么组就可以了,那么检测用户权限,就需要查出用户所在的组,然后再查出这个组(或者这些组)所拥有的权限,就可以得出用户所具备的权限,再进行验证即可。当然会比直接查询userPermission表绕一点点,不过相对比维护成本,这点点消耗不算什么。更何况我们其实仍然可以保存userPermission表,在分配用户组的时候,同时更新userPermission表即可。
这里可以看到,除了在分配用户权限方便以外,当你需要更改某类用户权限的时候,你只需要更改其所在组的权限,那么这个组下所有成员的权限也会随之更改,非常方便。
到这里用户、用户组的权限构成基本完成。它能解决大部分问题,可是我发现它仍然有一些小的问题。比如如果某个用户只有查权限,我不得不再新增一个用户组,搞得用户组也很多,怎么办呢?如果这个用户属于普通用户组,其实可以考虑也分配普通用户组给这个用户,然后再从普通用户组里“扣掉”增权限。要达到这样的效果,怎么处理呢?
其实很简单,我们刚才没有去掉的userPermission表派上用场,这个表存储了用户的实际单个权限,我们只需要增加一个字段标识用户是拥有这个权限,还是没有这个权限即可,这样可以解决两个问题:一是从现有用户组中扣掉某些权限,二是在现有用户组中,再给这个用户增加用户组以外的权限。来看一下userPermission表:

1
2
3
4
5
6
CREATE TABLE userPermission (
   userId int (10) unsigned NOT NULL ,
   permissionId int (10) unsigned NOT NULL ,
   has enum( 'yes' , 'no' ) NOT NULL ,
   PRIMARY KEY (userId, permissionId)
)

把用户1的增权限去掉,那么内容可能像这样:

1
2
3
4
5
6
7
8
9
10
+--------+--------------+-----+
| userId | permissionId | has |
+--------+--------------+-----+
|      1 |            1 | no  |
|      1 |            4 | yes |
|      2 |            1 | yes |
|      2 |            2 | yes |
|      2 |            4 | yes |
|      2 |            3 | yes |
+--------+--------------+-----+

这个用户依然在user组里,只不过user组所拥有的2个权限(add, select),他少了个add(ID为1被标记为no)权限而已。
嗯,这样做有解决了这个小问题,不过这个功能增强会让分配权限代码更复杂一些,不仅要给用户分配组,还可能需要操作具体权限,让他有或者让他没有相应的权限。
OK,简单的权限设计全部完成,只不过,细心的读者,你是否意识到,还少点什么呢?没错,即使到这里,整个权限验证还少了一块很重要的部分,那就是用户拥有这些权限,那么他能在哪里使用这些权限。考虑一个例子,一个论坛版主在他所管理的论坛版块里拥有删、改帖子的权限,他在其他非他所管理的版块就没有这些权限,可能在其他论坛版块他像是一个普通用户一样,我们上面讨论的权限设计如何做到这个验证呢?那么我个人觉得,权限设计到上面已经完成了,接下去这种情况,属于业务逻辑层的验证,我们从权限系统中已经获得用户的权限,那么在具体业务逻辑中,和权限进行绑定即可,以上例子可以用一个版块用户关系表来解决这个问题:

1
2
3
4
5
CREATE TABLE userBoard (
   userId int (10) unsigned NOT NULL ,
   boardId int (10) unsigned NOT NULL ,
   PRIMARY KEY (userId, boardId)
)

标记用户拥有哪些版块的管理权限,那么在严重用户拥有管理权限的时候,还要看当前版块是否是用户管辖内的版块,最终确定用户是否有操作权限。那么我将这类和业务逻辑相关的权限分配归到用户角色里,同样可以创建一系列角色,来管理用户所管辖的范围,比如超级版主,他也是具有管理删、改权限,只不过他的权限作用于全论坛,那么普通版主就需要指定论坛,这样来区分用户组和角色组我想会使整个权限系统更加清晰。
到这里,权限验证全部完成,以上没有具体实现代码,我相信这样已经足够了,具体的实现代码和业务逻辑由具体的应用实现吧。

http://www.phpfans.org/53.html

转载于:https://my.oschina.net/tenking/blog/28571

浅谈权限设计(来自深空老大)相关推荐

  1. 多数据库支持的应用程序设计(来自深空老大)

    2019独角兽企业重金招聘Python工程师标准>>> 以前做PHP应用,多数是单数据库数据查询和更新,顶多也是主从数据库的支持,实现起来相对简单.主从数据库的问题在于,当会话存储在 ...

  2. 浅谈数据库设计技巧(上)

    浅谈数据库设计技巧(上) 说到数据库,我认为不能不先谈数据结构.1996年,在我初入大学学习计算机编程时,当时的老师就告诉我们说:计算机程序=数据结构+算法.尽管现在的程序开发已由面向过程为主逐步过渡 ...

  3. 中鸣循迹机器人_浅谈机器人设计方法

    浅谈机器人设计方法 摘要: 机器人是人类完成智能化中非常重要的工具, 随着时代的发展, 机器 人已经在世界有了一定的发展,甚至很多国家机器人已经运用到实际的生活中 去. 而机器人的设计方法无疑是很多人 ...

  4. 浅谈工厂设计--java必备技能

    浅谈工厂设计–java必备技能 说到工厂,我就联想到了亚洲的大工厂富士康–接过订单然后按照固定的模板生产商品,其实java中工厂类中的工厂方法也是一样,接过参数,根据参数来生产需要的商品: 今天我们一 ...

  5. 浅谈购物中心设计之外立面设计注意点

    购物中心的主体定位中,可以通过外立面设计充分的发挥和展现个性,吸引八方游客,从而使购物中心的商圈辐射超越了地区的界限.具体来说,购物中心外立面设计需要注意哪些方面呢?我们今天就来浅谈购物中心设计之外立 ...

  6. 计算机中用户的分类有哪些,用户分类浅谈交互设计 -电脑资料

    说到网络产品,离不开的话题就是用户,就像传统行业的消费者, 不分类不好定位, 好的用户分类让我知道了我在追求哪些人,满足哪些人,影响哪些人.但分不好类又会错位,更糟,那怎样才能对某一款产品的用户群进行 ...

  7. 浅谈权限管理的设计与实现

    一.权限管理的意义 保证安全:避免误操作.人为破坏.数据泄露等. 数据隔离:不同的权限能看到及操作不同的数据,互不干扰. 职责明确:不同角色处理不同事务,细化职责,规范并简化流程. 二.权限管理系统的 ...

  8. [UWP]浅谈按钮设计

    一时兴起想谈谈UWP按钮的设计. 按钮是UI中最重要的元素之一,可能也是用得最多的交互元素.好的按钮设计可以有效提高用户体验,构造让人眼前一亮的UI.而且按钮通常不会影响布局,小小的按钮无论怎么改也不 ...

  9. 我的家乡网页设计_Graphic Design|康石石浅谈LOGO设计在作品集中的创作方法

    写在前面的话 平面设计范畴极广,其领域不仅限于常见的版式设计.海报设计.LOGO设计.VI设计.书籍装帧.广告设计.网页设计.在艺术留学申请过程中,学习平面设计的同学们需依据目标院校对作品集项目及页数 ...

最新文章

  1. YYH的苍天大竹(NOIP模拟赛Round 6)
  2. 计算机视觉与深度学习,看这本书就够了
  3. Python中异常处理的用法
  4. 【mysql】配置 选项文件
  5. 世界坐标系,摄像机坐标系、图像坐标系关系汇总
  6. 【转载】手动删除引用nuget如何还原
  7. mysql sum带条件_mysql – SUM()基于SELECT的不同条件
  8. 12-17 学习记录
  9. 颓废了1年+,今天开始勤(tui)奋(fei)啦
  10. 算法竞赛入门经典(刘汝佳版)例题与解答
  11. linux下安装redis报Mmmm... it seems like you don‘t have a redis executable. Did you run make install yet?
  12. 括号匹配(POJ2955)题解
  13. linux复制文件跳过相同,Linux中拷贝目录跳过指定文件的方法
  14. libgdx 打飞机游戏实现教程
  15. 用 screen 做串口终端
  16. 计算几何(判断顺时针/逆时针) - Clockwise or Counterclockwise - HDU 6857
  17. java新手入门学习指南
  18. NOI / 1.7编程基础之字符串题目排名状态提问15:整理药名
  19. WINDOWS 疑难杂症
  20. 安保巡更室内外定位系统解决方案

热门文章

  1. asp.net 的性能计数器
  2. 如何在DataGrid里面使用动态图形表示数字
  3. 【流媒體】jrtplib—VS2010下RTP开源协议库JRTPLIB3.9.1编译
  4. 堆状态分析的利器——valgrind的DHAT
  5. 行列式介绍及Eigen/OpenCV/C++的三种实现
  6. 设计模式之策略模式(Strategy)摘录
  7. C++ 中隐藏DOS调用的命令行窗口
  8. 【C++】mingw32-make+cmake:error: ‘nullptr‘ was not declared in this scope解决方法
  9. linux 从命令行启动,Linux下常见服务在命令行方式的启动
  10. python vs javascript_Python“是”vs JavaScript===