phpcms中的RBAC权限系统

**PHPCMS中的RBAC权限系统主要用到了4张数据表:管理员表,角色表,菜单表,菜单权限表。先来看看数据库的数据表结构:** ## admin 管理员表 |ID |字段 |类型 |Null |默认 | 索引 |额外 |注释| |:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| |1 |userid |mediumint(6) |unsigned| |PK |auto_increment |用户id |2 |username |varchar(20) |YES||INDEX| |用户名| |3 |password |varchar(32) |YES||| |密码| |4 |roleid |smallint(5) |YES |0|| |角色| |5 |encrypt |varchar(6) |YES ||| |加密因子 |6 |lastloginip |varchar(15) |YES| || | 最后登录ip |7 |lastlogintime |int(10) unsigned |YES| 0|| |最后登录时间 |8 |email |varchar(40) |YES ||| |Email |9 |realname |varchar(50) |NO ||| |真实姓名 |10 |card |varchar(255) |NO ||| |密保卡 ## admin_role 角色表 |ID |字段 |类型 |Null |默认 | 索引 |额外 |注释| |:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| |1 |roleid |tinyint(3) unsigned| | |PK |auto_increment |角色id| |2 |rolename |varchar(50) |NO | | | |角色名称| |3 |description |text |NO | | | |描述 |4 |listorder |smallint(5) unsigned| NO| 0| INDEX| |排序 |5 |disabled |tinyint(1) unsigned| NO| 0| INDEX| |状态:1,禁用 ## menu 菜单表 |ID |字段 |类型 |Null |默认 | 索引 |额外 |注释| |:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| |1 |id |smallint(6) unsigned |||PK |auto_increment |菜单id| |2 |name |char(40)| NO |||| 名称| |3 |parentid |smallint(6) |NO |0 |INDEX|| 父id| |4 |m |char(20) |NO | |INDEX|| m| |5 |c |char(20) |NO | |INDEX|| c| |6 |a |char(20) |NO | |INDEX|| a| |7 |data |char(100) |NO| ||| 附件参数| |8 |listorder |smallint(6) unsigned |NO |0 |INDEX|| 排序| |9 |display |enum('1','0') |NO |1 ||| 是否显示,1 显示| ## admin\_role\_priv 菜单权限表 |ID |字段 |类型 |Null |默认 | 索引 |额外 |注释| |:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| |1 |roleid |tinyint(3) unsigned | |0|PK|| 角色id| |2 |m |char(20) |NO| |INDEX|| m| |3 |c |char(20) |NO| |INDEX|| c| |4 |a |char(20) |NO| |INDEX|| a| |5 |data |char(30) |NO| ||| 附件属性| |6 |siteid |smallint(5) unsigned |NO |0 |INDEX|| 所属站点| ## 下面来简单分析一下4张表的关系: > 1.用户表中的每个用户有一个角色字段roleid,表明了该用户属于哪个角色。 > 2.角色表的主键为roleid,与用户表中的roleid相对应,还有角色名称,描述等,比如PHPCMS系统默认有超级管理员、总编、发布人员等角色。 > 3.管理员权限表中主键也是roleid,与角色表中的主键roleid相对应,表明了该角色拥有的后台操作权限。字段m、c、a分别代表的是模型 | 控制器 | 方法,因为PHPCMS本身也是MVC结构,所以更好地使权限系统的粒度细化到方法上面。 > 4.菜单表主要存放菜单属性,其中的m、c、a与管理员权限表中的字段相对应。 ## 最后来看看用户的操作及验证流程: 首先,用户在后台登录,如果登录成功,将roleid(角色id)存入SESSION,然后跳转到后台首页,在PHPCMS系统中,整个后台操作的部分都在admin模块中,所以该模块中所有的控制器均继承自admin类,并且在构造方法中执行了父类的构造方法(admin的构造方法)。那么,admin类的构造方法有执行了哪些操作呢? 首先是调用自身的 check_admin() 来判断用户是否登录,紧接着判断用户的权限: check_priv() ### check_priv() 方法源代码: ```php ## 格式略微修改 final public function check_priv() { if (ROUTE_M == 'admin' && ROUTE_C == 'index' && in_array(ROUTE_A, array('login', 'init', 'public_card'))) { return true; } if ($_SESSION['roleid'] == 1) { return true; } $siteid = param::get_cookie('siteid'); $action = ROUTE_A; $privdb = pc_base::load_model('admin_role_priv_model'); if (preg_match('/^public_/', ROUTE_A)) { return true; } if (preg_match('/^ajax_([a-z]+)_/', ROUTE_A, $_match)) { $action = $_match[1]; } $r = $privdb->get_one( array( 'm' => ROUTE_M, 'c' => ROUTE_C, 'a' => $action, 'roleid' => $_SESSION['roleid'], 'siteid' => $siteid ) ); if (!$r) { showmessage('您没有权限操作该项', 'blank'); } } ``` > 该方法首先判断当前正在进行的操作,如果是登录或者初始化操作,则退出。 > 然后判断角色是否为超级管理员(超级管理员默认为最高权限),如果是,依旧退出,或者如果当前方法为公开的(没有权限限制),同样退出。 > 最后加载 **admin\_role\_priv_model**,也就是管理员权限模型,获取当前要操作的模型 | 控制器 | 方法,利用 **admin\_role\_priv_model** 提供的方法进行查询,如果可以返回数据,则说明角色可以进行当前操作,反之,弹出提示信息:您没有权限操作该项,然后退出! 对了,忘了介绍后台菜单的生成过程啦!其实用到的还是admin类自身的方法:**admin_menu():** 不过该方法是在 **index.tpl.php** 模板中调用的,主要进行的操作是先取出菜单表中所有菜单,然后判断当前角色,如果为超级管理员,则直接返回菜单数组,反之,则将符合当前角色权限的菜单数组返回。 **以上就是PHPCMS系统的权限结构及操作流程!**

posted @ 2015-12-30 16:29  洋芋土豆  阅读(6220)  评论(2编辑  收藏  举报