Tag: TP/RBAC

关于TP中RBAC的学习笔记

没有评论

2010 年 11 月 08 日 at 下午 10:33分类:PHP | WEB开发

最近一段时间在研究TP的框架,自我感觉还行!用了三天左右的时间写了一个个人的博客!

今天在学习原来TP的基础上再来研究TP的RBAC扩展类!这个扩展类是关于用户的权限判断的!在大项目中用起来应该还是个不错的方法

要是在小型的项目中,那么用cookie或者是session判断下就行了!

在使用TP的RBAC之前,必须在配置文件中配置相关的参数信息如下:

‘USER_AUTH_ON’=>true,
‘USER_AUTH_TYPE’=>2,	 // 默认认证类型 1 登录认证 2 实时认证
‘USER_AUTH_KEY’=>’authId’,	// 用户认证SESSION标记
‘ADMIN_AUTH_KEY’=>’administrator’,	//管理员认证的识别号
‘USER_AUTH_MODEL’=>’User’,	// 默认验证数据表模型
‘AUTH_PWD_ENCODER’=>’md5′,	// 用户认证密码加密方式
‘USER_AUTH_GATEWAY’=>’/Index/login’,	// 默认认证网关
‘NOT_AUTH_MODULE’=>”,	 // 默认无需认证模块
‘REQUIRE_AUTH_MODULE’=>”,	 // 默认需要认证模块
‘NOT_AUTH_ACTION’=>’login,checklogin,logout’,	 // 默认无需认证操作
‘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’,

这样子配置好之后,我们在公共的操作Action中就可以用了!哦,不忘了加载官方提供扩展类!因为我们不管执行哪个操作,都需要判断操作者是否具有操作该方法的权限。因此我们通常是在初始化的函数_initialize函数里面就判断用户权限!要调用的方法是如下:

if(C(‘USER_AUTH_ON’)){

 dump($_SESSION);

 import(‘@.ORG.RBAC’);

 if(!RBAC::AccessDecision()){

 echo ( “你没有权限操作”.ACTION_NAME);

 $this->redirect(‘Index/login’);

 }

 }

当然,这是最最简单的方法,可以在这个基础上再加上一些更复杂的判断,

现在我们可以访问相应的操作方法!要是该方法不具备权限,就会输出:‘你没有权限+操作名’,这样子就说明,该操作者不具备操作该方法的权限

,此外我们要是有些模块是不需要权限认证,我们可以在配置文件的相关配置项里面添加!可以添加的有:默认必须认证的模块。默认无须认证的模块;

默认必须认证的方法和默认无须认证的方法!此外有一点必须记住:要是一个模块或者是一个方法同时出现在必须认证和无须认证里面,那么这个方法

肯定是必须认证的!除了在配置文件里面配置权限外!当然在配置文件里面的配置是很粗糙的!更重要的和最主要的权限问题还是通过数据库来解决的!

RBAC的数据库表有5个:

1、用户表users:这个不用多讲,主要是记录用的用户名和密码啊,状态啊等基本信息的!

2、角色表role:这个表是权限的重要部分!分配权限主要是通过角色来分配的!而不是将权限分配给个某一个用户!角色表就相当于是多个具有相等权限的

用户组合在一起的一个组!我们分配权限主要是对这个组来分配权限的!同一个角色可以包含多个用户,一个用户也可以扮演多个角色,是一个多对多的关

系。在角色表中主要的字段有:主键id,该角色的昵称name,该角色的父角色pid,一般情况下,默认为0,记住,角色可以是可以继承的!但是值可以继承

两层,不能超过两层!继承了父角色的子角色,具有父角色的所有权限,同时还具有本身的权限!最后一个字段状态字段:status,只有在开启的时候才有效

3、节点表:node 这个表就是权限的价值体现!字段有:主键id,第二个字段是name,此处的name值只有三种情况,1.当前项目的名称,2.当前操作的模

块也就是Action,3.要设置权限控制的函数方法。要想对函数方法进行权限控制,那么必须让操作者有操作项目的权限和操作该模块的权限,然后才能控制

函数方法的权限!因此在后面的第二个字段是PID,很明显:项目的pid的0,该项目下的模块是该项目的node_id,那么该模块下面的方法的pid是对应模块

的node_id。者三者永远是父子的关系!第四个字段:level,等级,这个字段很简单,记住,项目的等级是1,模块的等级是2,函数方法的等级3,在RBAC

里面都是这么定的。第五个字段是status,状态,必须保证是开启状态的,要是在飞开启状态,那么相应的权限就丢失了!还有一个字段是title,是对name

的昵称。

4、用户和角色的关联表:user_role:主要是把相应的用户划分到相应的角色中,字段只有两个:role_id和user_id分别对应的是角色的id和用户的id

5、权限表:access;原理是:把某一个节点的权限给一个角色!比如一个角色要访问APP项目下面Index操作下面的index方法,那么我们授权的方式是:

首先对该角色授予操作APP项目的权限,然后授予操作Index模块的权限,最后授予具体某个方法的权限!具体的授权:在数据表中,我们有字段:

role_id,node_id,pid,level等,这四个字段是必须的!授权方式:在相应的角色role_id后面的node_id里面填上相应节点的id,一般情况下pid可以不写!

后面的level也很重要!此处的level是指node_id的等级!如果指定的node_id是项目名,那么此level为1,模块名为2,函数方法为3,此处的等级和节点表

里面的相对应的等级应该是完全一样的,就这三中情况!千万要注意,此处的level不可以写错!

数据库的解释就写这么多了!已经很详细了吧!

我们要对具体的用户授权,只需要把相应操作方法和用户的相关信息写到相关的数据表中就行了!其实这个还是蛮简单的!

记住要在用户登录的时候执行一定要执行RBAC::saveAccessList();缓存登录信息

可以借鉴下面的额登录方法

public function checklogin()

 {

 if(empty($_POST['username'])) {

 $this->error(‘帐号错误!’);

 }elseif (empty($_POST['passwd'])){

 $this->error(‘密码必须!’);

 }

 $map['username'] = $_POST['username'];

 import(‘@.ORG.RBAC’);

 $authInfo = RBAC::authenticate($map);

 if(false === $authInfo){

 $this->error(‘帐号不存在或已禁用!’);

 }else{

 if($authInfo['password'] != md5($_POST['passwd'])) {

 $this->error(‘密码错误!’);

}

$_SESSION[C('USER_AUTH_KEY')] = $authInfo['id'];

 //如果为管理员

if($authInfo['account']==’admin’) {

 $_SESSION['administrator'] = true;

}

 RBAC::saveAccessList();

 $this->success(‘登录成功!’);

 }

 }

当然这个只是我写练习的时候写的!肯定有很多的不好!!