对ThinkPHP中RBAC权限控制的理解和尝试
首先甩一波RBAC的百科:基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。
简单地说,就是某用户对应一个身份,而此身份拥有多种操作权限,该用户可以使用这些操作权限,但不能做不属于这个身份的权限动作。
其实看了那么多资料都感觉云里雾里,感觉好像懂了但又不是完全懂,所以想自己写一个demo出来理解一下。
这篇文就少贴代码了...毕竟文字比较好理解吧...
(1)首先是建数据表。
用户表:user(int uid,varchar name,int password,tinyint status);
用户角色关系表:user_role(int uid,int rid);
角色表:role(int rid,varchar name,int pid,varchar remark,tinyint status);
角色节点关系表:role_node(int rid,int nid);
节点表:node(int nid,varchar name,varchar title,int pid,tinyint level,tinyint status);
菜单表:menu(int mid,varchar title, varchar path,int pid, tinyint level,int nid);
PS:这里用户和角色表比较好理解,节点表就是权限表,每个节点对应一个权限,而菜单表则是显示给用户看的菜单(或者说是导航栏),诶那有人会问节点和菜单有什么不同,节点是每个权限(比如增删查改4个权限),但是导航栏里面不可能把这4个权限都放进去吧,应该只有“查看”作为一个导航项,其他的作为“查看”那个页面的分立功能。
(2)写类。
class User
{ public function __construct();//连接数据库,连接session
public function login();//用户登录,其中调用各种方法获取:用户信息User::userInfo,用户对应角色的信息User::userToRole&Role::roleInfo,用户对应角色的节点的信息Role::roleToNode&Node::nodeInfo,根据节点所存在的菜单信息Menu::filterMenu,并把这些信息存储在session里
public function info();//读取用户权限
public function authority();//判断用户是否有权限
public function logout();//退出登录,销毁session
private function userToRole();//根据uid查询role
private function userInfo();//获取用户信息
}
class Role
{ public function __construct();//连接数据库
public function roleToNode();//根据rid查询所属的node
public function roleInfo();//根据rid查询role的详细信息
}
class Node
{ public function __construct();//连接数据库
public function nodeInfo();//根据nid查询node的详细信息
}
class Menu
{ public function __construct();//连接数据库
public function filterMenu();//根据nodeArray,用node和menu的对应关系,筛选出可访问的menu
}
PS:因为只是做了个demo,还是挺简单的,只有查询功能,没有增删改,诶其实我也本来是本着理解RBAC的目的来做的,嗯理解就好。想要具体代码就私我吧,因为写的不怎么样就不贴上来了...
(3)功能测试
登录:
require_once"Class/UserClass.php"; $user = new User(); $user->login(); echo "<a href=test.php>查看权限</a>";
查看权限:
require_once"Class/UserClass.php"; $user = new User(); $user->info();
访问每个页面:
require_once"Class/UserClass.php"; $pagename = basename($_SERVER['PHP_SELF']);; $user = new User(); if(!$user->authority($pagename)){ require('404.php'); @header('HTTP/1.1 404 Not Found'); @header('Status: 404 Not Found'); exit; }else{ //正常显示 echo $pagename; }
退出登录:
require_once"Class/UserClass.php"; $user = new User(); $user->logout();
参考网址:
http://www.lyblog.net/detail/552.html
http://www.cnblogs.com/tanteng/archive/2012/11/25/2787597.html
转载于:https://my.oschina.net/mcstudio/blog/724612