分享:thinkphp RBAC 详解

来源:互联网 发布:会计证考试软件 编辑:程序博客网 时间:2024/05/10 16:33

转载::http://www.zoneself.org/2012/03/06/content_1069.html


一直在用thinkphp做项目,tp有个规定的功能很好,就是分权限管理。以前大体看过THINKPHP 的RBAC的介绍,不过没仔细研究 ,通过这几次的项目实训,发现RBAC.Class.php还是非常精炼的,使用起来也是够简单的,而且很灵活。但是恰恰是这灵活性让新手感到迷惑!好了,不多说了,一下内容是给新手看的,老手可以略过了。下面小涛说一下对RBAC的大体理解:
先看下官方给的实例所用到的数据表,在手册中就能找到:

RBAC 用到了5个数据表

think_user (用户表)

think_role (用户分组表)

think_node (操作节点)

think_role_user (用户和用户分组的对应)

think_access (各个操作和用户组的对应)

这里重点说一下 think_note

think_note 其实就是记录下了整个网站操作对应的 项目名称 模块名称 和 操作名称。

字段name就是当项目,模块或者操作的名称了。

字段PID 记录他们的从属关系,比如某一个模块是属于哪个项目,某个操作属于哪个模块。

     字段level 表示该节点的层级 换句话就是说 level=1 为项目 ,level=2为模块 ,level=3就是操作了,比如说 admin项目,他的PID 就是 0 (项目的PID都是0) level就是1,nane就是admin了,admin项目下面有的user模块,它的level就应该是2,pid就是admin的id, admin下面user模块的add操作,level就该是3了,pid就应该是前面的user对应的ID.

 再说下 rbac类的 方法

authenticate($map,$model=”)方法 传入查询用户的条件和用户表的MODEL 返回数组包含用户的信息

saveAccessList($authId=null)方法 传入用户的ID 此方法不返回值,只是设置 $_SESSION['_ACCESS_LIST']的值,其中包含了所有该用户对应的用户组的有权限操作的所有节点 $_SESSION['_ACCESS_LIST']['项目名']['模块名']['操作名'],以后判断权限就是判断当前项目,模块和操作是否在 $_SESSION['_ACCESS_LIST']中能找到。s

checkAccess() 方法 检测当前模块和操作是否需要验证 返回bool类型

checkLogin()方法 检测登录

AccessDecision($appName=APP_NAME) 方法 就是检测当前项目模块操作 是否在$_SESSION['_ACCESS_LIST']数组中,也就是说 在 $_SESSION['_ACCESS_LIST'] 数组中$_SESSION['_ACCESS_LIST']['当前操作']['当前模块']['当前操作']是否存在。如果存在表示有权限 否则返回flase。

 getAccessList($authId) 方法 通过查询数据库 返回权限列表 $_SESSION['_ACCESS_LIST']的值了。

 

    上面的记录就是 我个人对RBAC的理解。在开发过程中还遇到个问题,我的项目一有一个 ,但是我又想把 几个模块分开管理。想了半天发现AccessDecision($appName=APP_NAME) 是可以传项目名称的。那么 我们先分几个组,也就是LEVEL=1,PID=0的,然后 把模块分组管理。在使用的时候就麻烦点。每个分组都建一个基类,在基类中if (! RBAC::AccessDecision ()) { 手动给 AccessDecision添加参数,就是当前分组的名称。然后属于某个分组的模块就引用这基类。这样就达到了同一项目下 分组管理模块的功能了。

最后说一下RBAC.Class.php的大体意思:
RBAC.Class.php中有若干函数,其中我们新手直接打交道的却只有一下几个:
authenticate() saveAccessList() checkLogin() AccessDecision()
什么?你问我它们是干啥的?好,且听我先啰嗦几句认证的过程。
1、检查系统是否开启认证功能C(‘USER_AUTH_ON’)
2、检查当前操作是否需要认证
3、如果当前操作需要认证,检查当前用户是否具有权限。if(有),啥也不做。
4、if(没有),检查原因。如果是因为没有登录,跳转至登录页面。如果是没有权限,报错。
这4步就完成了用户的认证,其中 AccessDecision()就搞定了前三步!
而checkLogin()负责第4步中检查浏览器是否登录。
哈哈,还剩下两个了,我想来想去,觉得还是应该放到第二步中来说明

第二步:
既然RBAC.Class.php这么强,帮我们搞定了这么多工作,那么我们是不是啥也不用做了?
答案让大家很失望,我们还需要写一些代码。
首先我们需要在要认证模块中加入一下代码

protected function _initialize(){

Import ( ‘ORG.Util.RBAC’ );
if (! RBAC::AccessDecision ())//未通过认证
{
// 登录检查
RBAC::checkLogin();
// 提示错误信息 无权限
$this->error ( L ( ‘_VALID_ACCESS_’ ) );

复制代码
目的就是告诉程序,在未通过认证的时候,需要怎么做。
另外,我们需要在用户输入用户名和密码的时候检测一下用户是否输入的正确,这个东东也就是所谓的认证网关。
名称在config.php中用’USER_AUTH_GATEWAY’定义。
我的代码如下所示:

//生成认证条件
$map = array();
$map['account'] = $_POST['account'];
$map["status"] = array(‘gt’,0);
import ( ‘ORG.Util.RBAC’ );
$authInfo = RBAC::authenticate($map);
//使用用户名、密码和状态的方式进行认证
if(false === $authInfo)
{
                 $this->error(‘帐号不存在或已禁用!’);
}
else
{

if($authInfo['password'] != md5($_POST['password']))
{
$this->error(‘密码错误!’);
}
$_SESSION[C('USER_AUTH_KEY')] = $authInfo['id'];
if($authInfo['account']==’admin’)
{
$_SESSION[C('ADMIN_AUTH_KEY')] = true;
}
// 缓存访问权限
RBAC::saveAccessList();
$this->success(‘登录成功!’);

           }

复制代码
好了,这样一个完整的RBAC认证就完成了。

技术分享,技术交流,小涛与您共同成长……


ThinkPHP的RBAC(基于角色权限控制)详解

一、什么是RBAC

基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。

在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。

在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。

二、ThinkPHP中的RBAC

先看下官方给的实例所用到的数据表,通过5张表实现权限控制,定义如下:

RBAC 要用到5个数据表

think_user (用户表)

think_role (用户分组表)

think_node (操作节点)

think_role_user (用户和用户分组的对应)

think_access (各个操作和用户组的对应)


用户表


角色表,有哪些角色,该角色与对应的userid用户相关联


根据用户表的id给出对应的角色id相关联,也就是给用户分配角色,比如userid为3的角色为2,根据role角色表,7代表员工的角色


access表,权限表,比如角色id为2,也就是员工的权限,可以的对应的结点


结点表,代表有哪些应用-模块-模块方法,并且定义了之间的一种关系,比如noteid为30的是Public模块,noteid为31,32,33,34的方法add,insert,edit,update都属于Public。noteid为85的test方法,属于noteid为84的Game模块下的方法。

三、config配置文件详解

我们看看thinkphp官方示例中的config文件:

复制代码
array(        'APP_AUTOLOAD_PATH'=>'@.TagLib',        'SESSION_AUTO_START'=>true,        'USER_AUTH_ON'              =>true,        'USER_AUTH_TYPE'            =>1,        // 默认认证类型 1 登录认证 2 实时认证        'USER_AUTH_KEY'             =>'authId',    // 用户认证SESSION标记        'ADMIN_AUTH_KEY'            =>'administrator',        'USER_AUTH_MODEL'           =>'User',    // 默认验证数据表模型        'AUTH_PWD_ENCODER'          =>'md5',    // 用户认证密码加密方式        'USER_AUTH_GATEWAY'         =>'/Public/login',// 默认认证网关        'NOT_AUTH_MODULE'           =>'Public',    // 默认无需认证模块        'REQUIRE_AUTH_MODULE'       =>'',        // 默认需要认证模块        'NOT_AUTH_ACTION'           =>'',        // 默认无需认证操作        'REQUIRE_AUTH_ACTION'       =>'',        // 默认需要认证操作        'GUEST_AUTH_ON'             =>false,    // 是否开启游客授权访问        'GUEST_AUTH_ID'             =>0,        // 游客的用户ID        'DB_LIKE_FIELDS'            =>'title|remark',        'RBAC_ROLE_TABLE'           =>'think_role',        'RBAC_USER_TABLE'           =>'think_role_user',        'RBAC_ACCESS_TABLE'         =>'think_access',        'RBAC_NODE_TABLE'           =>'think_node',        'SHOW_PAGE_TRACE'=>1//显示调试信息    );
复制代码

大家看注释就应该懂大半了,其中Public模块是无需认证的,道理很简单,没登录之前大家都是游客身份,如果登录页面也要权限,那从哪里登录呢?是吧,呵呵。默认网关地址就是认证失败,没有权限跳转到此处,重新登陆。ADMIN_AUTH_KEY表示超级管理员权限,如果你在user表建立一个名为admin的用户,那么这个用户就是超级管理员,不用给它分配权限,什么权限都有,为什么要设置一个这样的管理员,因为当你把权限分配错了容易引起系统权限混乱,搞得大家都访问不了,这时候超级管理员就来了。

四、RBAC类的几个重要的方法

authenticate($map,$model=”)方法 传入查询用户的条件和用户表的MODEL 返回数组包含用户的信息

saveAccessList($authId=null)方法 传入用户的ID 此方法不返回值,只是设置 $_SESSION['_ACCESS_LIST']的值,其中包含了所有该用户对应的用户组的有权限操作的所有节点 $_SESSION['_ACCESS_LIST']['项目名']['模块名']['操作名'],以后判断权限就是判断当前项目,模块和操作是否在 $_SESSION['_ACCESS_LIST']中能找到。s

checkAccess() 方法 检测当前模块和操作是否需要验证 返回bool类型

checkLogin()方法 检测登录

AccessDecision($appName=APP_NAME) 方法 就是检测当前项目模块操作 是否在$_SESSION['_ACCESS_LIST']数组中,也就是说 在 $_SESSION['_ACCESS_LIST'] 数组中$_SESSION['_ACCESS_LIST']['当前操作']['当前模块']['当前操作']是否存在。如果存在表示有权限 否则返回flase。

getAccessList($authId) 方法 通过查询数据库 返回权限列表 $_SESSION['_ACCESS_LIST']的值了。


0 0
原创粉丝点击