浅析Yii中使用RBAC的完全指南(用户角色权限控制)


Posted in PHP onJune 20, 2013

写在前面
    * 我的feed地址已经修改为: http://feeds.imdong.net ,请更新您的阅读器。
    * 以下内容适合Yii 1.0.x,其他版本可能有略微的差别。
    * 根据您的评论和反馈,本文会不断进行修改和补充,以方便新学习者。

开始准备
Yii提供了强大的配置机制和很多现成的类库。在Yii中使用RBAC是很简单的,完全不需要再写RBAC代码。所以准备工作就是,打开编辑器,跟我来。
设置参数、建立数据库
在配置数组中,增加以下内容:

‘components‘ => array(
    //……
    ‘authManager‘=>array(
            ‘class‘=>‘CDbAuthManager‘,//认证类名称
            ‘defaultRoles‘=>array(‘guest‘),//默认角色
            ‘itemTable‘ => ‘pre_auth_item‘,//认证项表名称
            ‘itemChildTable‘ => ‘pre_auth_item_child‘,//认证项父子关系
            ‘assignmentTable‘ => ‘pre_auth_assignment‘,//认证项赋权关系
        ),
   //……

那这三个数据表怎么建立呢?很简单,去看framework/web/auth/schema.sql。注意要和你的自定义的表名称对应起来。比如SQL文件中的AuthItem你要修改为pre_auth_item。然后在数据库中运行这个SQL文件中的语句。

了解概念
你可能要问,剩下的代码呢?我告诉你,没有啦。RBAC系统就这样建立起来了。但是为了使用它,你需要了解它的运行机制。我会尽量讲的??乱坏恪??ü俜降?BAC文档在这里,但是我曾经看了4-5遍才明白。)

三个概念
你需要了解的是,授权项目可分为operations(行动),tasks(任务)和 roles(角色)。
一个用户拥有一个或者多个角色,比如,我们这里有三个角色:银行行长、银行职员、顾客。我们假设:
    * 张行长 有角色:银行行长、银行职员、顾客(人家自己可以存钱嘛)。
    * 王职员 有角色:银行职员、顾客。
    * 小李 有角色:顾客。

那么,相应的,只要顾客可以做的事情,小李就可以做,王职员和张行长也可以。银行职员可以做的事情,王职员和张行长都可以做,小李就不可以了。

比如,一个“顾客”可以存钱,那么拥有“顾客”角色的张行长、王职员、小李都可以存钱。“银行职员”可以打印顾客的交易记录,那么有“银行职员”角色的张行长和王职员都可以,而小李不行,必须找一个有“银行职员”角色的人才可以打印详细的交易记录。一个“银行行长”才可以进入银行钱库提钱,那么只有张行长可以,因为它才有“银行行长”的角色。
这就是基于角色的认证体系,简称RBAC。

角色的继承
角色是可以继承的,比如我们规定如下:
    * 凡是“银行行长”都是“银行职员”,也就是说,只要银行职员可以做的事情,银行行长都可以做。
    * 凡是“银行职员”都是顾客,同上,顾客可以做的事情银行职员也可以做。
那么角色关系就变成了:
    * 张行长 有角色:银行行长。
    * 王职员 有角色:银行职员。
    * 小李 有角色:顾客。
这样更简单了,这就是角色的继承。

任务的继承
一个任务(task)是可以包含另外一个任务的,我们举个例子,比如“进入银行”。
我们设定“顾客”这个角色有“进入银行”的权限。也就是说,“顾客”可以执行“进入银行”的任务。接下来,我们假设“进入柜台”是进入银行的父权限,也就是说,“进入柜台”包含“进入银行”。只要能“进入柜台”的人都可以“进入银行”。我们把“进入柜台”这个任务权限给“银行职员”。

那么从角色上来说,王职员可以进入银行,因为王职员的角色是“银行职员”,而“银行职员”包含了“顾客”的角色。那么“顾客”可以进行的“任务”对于“银行职员”来说也是可以进行的。而“顾客”可以“进入银行”,那么王职员也可以“进入银行”。这是角色的继承带来的。

我们再假设有个赵领导,是上级领导,可以进入柜台进行视察。那么,我们的任务关系是:
    * 赵领导 有任务:进入柜台。
那么,赵领导就可以“进入银行”。因为“进入银行”是被“进入柜台”包含的任务。只要可以执行“进入柜台”的人都可以执行“进入银行”。这就是任务的继承。

关于行动
行动是不可划分的一级。也就是说。而一个行动是不能包含其他行动的。假设我们有个行动叫“从银行仓库中提钱”。我们把这个行动作包含“进入柜台”。那么只要可以执行“从银行仓库中提钱”的角色都可以执行“进入柜台”这个任务。

三者关系
    * 一个角色可以包含另外一个或者几个角色。
    * 一个角色可以包含另外一个或者几个任务。
    * 一个角色可以包含另外一个或者几个行动。
    *
    * 一个任务可以包含另外一个或者几个任务。
    * 一个任务可以包含另外一个或者几个行动。
    *
    * 一个行动只能被角色或者任务包含,行动是不可以包含其他,也不可再分。
这样,就形成了一个权限管理体系。关于“任务”和“行动”,你不必思考其字面上的意义。这两者就是形成两层权限。

进行赋权
我们建立了RBAC权限管理,就需要进行对权限的WEB管理。这些就需要你自己写代码了。
根据不同种类的项目调用下列方法之一定义授权项目:
    * CAuthManager::createRole
    * CAuthManager::createTask
    * CAuthManager::createOperation
一旦我们拥有一套授权项目,我们可以调用以下方法建立授权项目关系:
    * CAuthManager::addItemChild
    * CAuthManager::removeItemChild
    * CAuthItem::addChild
    * CAuthItem::removeChild
最后,我们调用下列方法来分配角色项目给各个用户:
    * CAuthManager::assign
    * CAuthManager::revoke
下面我们将展示一个例子是关于用所提供的API建立一个授权等级:

$auth=Yii::app()->authManager;
    $auth->createOperation('createPost','create a post');
    $auth->createOperation('readPost','read a post');
    $auth->createOperation('updatePost','update a post');
    $auth->createOperation('deletePost','delete a post');
    $bizRule='return Yii::app()->user->id==$params["post"]->authID;';
    $task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);
    $task->addChild('updatePost');
    $role=$auth->createRole('reader');
    $role->addChild('readPost');
    $role=$auth->createRole('author');
    $role->addChild('reader');
    $role->addChild('createPost');
    $role->addChild('updateOwnPost');
    $role=$auth->createRole('editor');
    $role->addChild('reader');
    $role->addChild('updatePost');
    $role=$auth->createRole('admin');
    $role->addChild('editor');
    $role->addChild('author');
    $role->addChild('deletePost');
    $auth->assign('reader','readerA');
    $auth->assign('author','authorB');
    $auth->assign('editor','editorC');
    $auth->assign('admin','adminD');

也就是说,你需要自己写一个管理界面,来列出你的角色、任务、行动,然后可以在这个界面上进行管理。比如增加、删除、修改。

权限检查
假设你在你的管理界面进行了赋权,那么可以在程序里面进行权限检查:

if(  Yii::app()->user->checkAccess('createPost')  )
{
    // 这里可以显示表单等操作
} else {
    // 检查没有通过的可以跳转或者显示警告
}

上面的代码就检查了用户是否可以执行“createPost”,这createPost可能是一个任务,也可以是一个行动。

其他的
对于很多说Yii权限体系RBAC不好用的人其实都没有看懂文档。综合我的体验,我感觉Yii框架的RBAC是我用过的框架里面最好用的。而且是需要自己写代码最少的。
Yii的RBAC有更加高级的用法,比如“业务规则”,“默认角色”。你可以去参考官方文档。
我知道,会有部分人仍旧不理解RBAC,或者不会用Yii的RBAC。没有关系,你可以在下方的评论框里提问。
happy Yii !

PHP 相关文章推荐
利用 window_onload 实现select默认选择
Oct 09 PHP
php中对2个数组相加的函数
Jun 24 PHP
PHP时间戳 strtotime()使用方法和技巧
Oct 29 PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
Jul 08 PHP
php字符串替换函数substr_replace()用法实例
Mar 17 PHP
php实现指定字符串中查找子字符串的方法
Mar 17 PHP
php关联数组快速排序的方法
Apr 17 PHP
thinkPHP下的widget扩展用法实例分析
Dec 26 PHP
PHP实现链式操作的原理详解
Sep 16 PHP
php UNIX时间戳用法详解
Feb 16 PHP
ThinkPHP实现图片上传操作的方法详解
May 08 PHP
laravel7学习之无限级分类的最新实现方法
Sep 30 PHP
php中0,null,empty,空,false,字符串关系的详细介绍
Jun 20 #PHP
解析PHP中数组元素升序、降序以及重新排序的函数
Jun 20 #PHP
解析php中的fopen()函数用打开文件模式说明
Jun 20 #PHP
深入解析PHP内存管理之谁动了我的内存
Jun 20 #PHP
解析php中die(),exit(),return的区别
Jun 20 #PHP
有关PHP性能优化的介绍
Jun 20 #PHP
数组与类使用PHP的可变变量名需要的注意的问题
Jun 20 #PHP
You might like
我的论坛源代码(二)
2006/10/09 PHP
php空间不支持socket但支持curl时recaptcha的用法
2011/11/07 PHP
PHP反转字符串函数strrev()函数的用法
2012/02/04 PHP
PHP 面向对象程序设计(oop)学习笔记 (四) - 异常处理类Exception
2014/06/12 PHP
ThinkPHP分页实例
2014/10/15 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
PHP中rename()函数的妙用讲解
2019/02/28 PHP
javascript结合CSS实现苹果开关按钮特效
2015/04/07 Javascript
javascript通过元素id和name直接取得元素的方法
2015/04/28 Javascript
AngularJS入门教程之链接与图片模板详解
2016/08/19 Javascript
JavaScript实现页面无操作倒计时退出
2016/10/22 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
解决在vue+webpack开发中出现两个或多个菜单公用一个组件问题
2017/11/28 Javascript
python复制文件代码实现
2013/12/23 Python
python线程、进程和协程详解
2016/07/19 Python
python中(str,list,tuple)基础知识汇总
2018/02/20 Python
Python自然语言处理 NLTK 库用法入门教程【经典】
2018/06/26 Python
Django中使用第三方登录的示例代码
2018/08/20 Python
详解python多线程之间的同步(一)
2019/04/03 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
浅析python实现动态规划背包问题
2020/12/31 Python
python爬取豆瓣电影排行榜(requests)的示例代码
2021/02/18 Python
丝绸和人造花卉、植物和树木:Nearly Natural
2018/11/28 全球购物
泰国的头号网上婴儿用品店:Motherhood.co.th
2019/04/09 全球购物
Antler英国官网:购买安特丽行李箱、拉杆箱
2019/08/25 全球购物
Janie and Jack美国官网:GAP旗下的高档童装品牌
2019/09/09 全球购物
远东集团网络工程师面试题
2014/10/20 面试题
珍珠鸟教学反思
2014/02/01 职场文书
乡村文明行动实施方案
2014/03/29 职场文书
2014年社区党建工作总结
2014/11/11 职场文书
离婚协议书样本
2015/01/26 职场文书
立春观后感
2015/06/18 职场文书
教育教学读书笔记
2015/07/02 职场文书
详解Python+OpenCV进行基础的图像操作
2022/02/15 Python
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server
SQL Server中搜索特定的对象
2022/05/25 SQL Server