深入解析yii权限分级式访问控制的实现(非RBAC法)


Posted in PHP onJune 13, 2013

yii framework 提供了2套权限访问系统,一套是简单的filter(过滤器)模式,另一套是复杂全面的RBAC模式,我这里要讲的是第一套(因为我也刚刚学到这里)。如 果你有研究过YII官方的demo blog,一定知道,比如,由gii自动生成的user模块,自动附带了简单的filter权限分配功能,具体细节请参照blog手册的“用户验证”一章 节,以及yii官方指南的“验证和授权”一章节。(注意,我这里所指的模块,只是我个人对与user有关的文件的统称,与yii文件系统的模块 (module)含义不同。)
关于权限分配的文件大多在controllers里,比如打开UserController.php文件你会看到2个类函数。

public function filters() 
     { 
      return array( 
       'accessControl',               // 实现CRUD操作的访问控制。 
       'postOnly + delete', 
         ); 
     }  public function accessRules()              //这里就是访问规则的设置。 
     { 
      return array( 
         array('allow',              // 允许所有用户执行index,view动作。 
           'actions'=>array('index','view'), 
           'users'=>array('*'), <span></span>           
           ),                    
         array('allow',             // 只允许经过验证的用户执行create, update动作。 
            'actions'=>array('create','update'), 
            'users'=>array('@'),       // @号指所有注册的用户 
             ), 
         array('allow',             // 只允许用户名是admin的用户执行admin,delete动作 
             'actions'=>array('admin','delete'), 
             'users'=>array('admin'), 
             ),                   //admin就是指用户名是admin的用户,以硬编码的形式分配用户权限。 
             array('deny',           // 拒绝所有的访问。 
             'users'=>array('*'), 
             ), 
         ); 
     }

关于更多的访问规则的设定请参照官方文件http://www.yiiframework.com/doc/api/1.1/CAccessControlFilter
好了,现在要开始按照我们自己的需求设置适合自己的权限分配了。我们希望filter访问控制模式能更完美一点,按照常识,我们希望它能按照数据库里user表里不同级别用户,实行不同的授权,而不是用硬编码的形式控制。

回到demo blog,我先对数据库的tbl_user表做修改,在原来的基础上加上role一项。对原来的用户信息记录添加role的value为"管理员"或"一般用户"。
然后依次执行以下3个步骤:
1. 创建组件WebUser,它是对CWebUser的扩展。
2. 修改config/main.php文件。
3.修改accessRules()。
具体细节如下:
1.WebUser.php 组件代码:

<strong><?php  // this file must be stored in: 
 // protected/components/WebUser.php 
 class WebUser extends CWebUser { 
   // Store model to not repeat query. 
   private $_model; 
   // Return first name. 
   // access it by Yii::app()->user->first_name 
   function getFirst_Name(){ 
     $user = $this->loadUser(Yii::app()->user->id); 
     return $user->first_name; 
   } 
   // This is a function that checks the field 'role' 
   // in the User model to be equal to 1, that means it's admin 
   // access it by Yii::app()->user->isAdmin() 
   function isAdmin(){ 
     $user = $this->loadUser(Yii::app()->user->id); 
     if ($user==null) 
         return 0; 
     else 
         return $user->role == "管理员"; 
   } 
   // Load user model. 
   protected function loadUser($id=null) 
     { 
         if($this->_model===null) 
         { 
             if($id!==null) 
                 $this->_model=User::model()->findByPk($id); 
         } 
         return $this->_model; 
     } 
 } 
 ?></strong>

2.在config/main.php找到如下代码,添加标红色的代码。
   'components'=>array(
        'user'=>array(
            // enable cookie-based authentication
            'allowAutoLogin'=>true,
             'class'=>'WebUser',
        ),

3.找到需要更改权限的controller类,对accessRules()函数做修改,比如对前文的accessRules()函数做如下修改:
public function accessRules()  //这里就是访问规则的设置。     { 
     return array( 
         array('allow',                     // 允许所有用户执行index,view动作。 
             'actions'=>array('index','view'), 
             'users'=>array('*'),         //*号标识所有用户包括注册的、没注册的、一般的、管理员级的 
         ), 
         array('allow',                      // 只允许经过验证的用户执行create, update动作。 
             'actions'=>array('create','update'), 
             'users'=>array('@'),       // @号指所有注册的用户 
         ), 
         array('allow',                     // 只允许用户名是admin的用户执行admin,delete动作 
             'actions'=>array('admin','delete'), 
             'expression'=>'yii::app()->user->isAdmin()', 
             //这样只有标识为“管理员”的用户才能访问admin,delete动作 
         ), 
         array('deny',  // 拒绝所有的访问。 
             'users'=>array('*'), 
         ), 
     );

工作完成!
PHP 相关文章推荐
PHP 和 MySQL 开发的 8 个技巧
Jan 02 PHP
php zip文件解压类代码
Dec 02 PHP
php基于双向循环队列实现历史记录的前进后退等功能
Aug 08 PHP
ThinkPHP在Cli模式下使用模板引擎的方法
Sep 25 PHP
thinkphp在低版本Nginx 下支持PATHINFO的方法分享
May 27 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
Aug 29 PHP
php判断是否为ajax请求的方法
Nov 29 PHP
php 人员权限管理(RBAC)实例(推荐)
May 24 PHP
php实现自定义中奖项数和概率的抽奖函数示例
May 26 PHP
PHP实现的函数重载功能示例
Aug 03 PHP
关于laravel 数据库迁移中integer类型是无法指定长度的问题
Oct 09 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
Aug 03 PHP
PHP 基于Yii框架中使用smarty模板的方法详解
Jun 13 #PHP
关于PHP二进制流 逐bit的低位在前算法(详解)
Jun 13 #PHP
php读取二进制流(C语言结构体struct数据文件)的深入解析
Jun 13 #PHP
基于PHP Socket配置以及实例的详细介绍
Jun 13 #PHP
深入php socket的讲解与实例分析
Jun 13 #PHP
PHP数据类型的总结分析
Jun 13 #PHP
如何用C语言编写PHP扩展的详解
Jun 13 #PHP
You might like
SWFUpload与CI不能正确上传识别文件MIME类型解决方法分享
2011/04/18 PHP
php实现统计网站在线人数的方法
2015/05/12 PHP
PHP内存缓存功能memcached示例
2016/10/19 PHP
Yii2实现跨mysql数据库关联查询排序功能代码
2017/02/10 PHP
php格式文件打开的四种方法
2018/02/24 PHP
laravel 实现划分admin和home 模块分组
2019/10/15 PHP
基于jQuery的让非HTML5浏览器支持placeholder属性的代码
2011/05/24 Javascript
js 连接数据库如何操作数据库中的数据
2012/11/23 Javascript
ajax异步刷新实现更新数据库
2012/12/03 Javascript
JavaScript的模块化:封装(闭包),继承(原型) 介绍
2013/07/22 Javascript
JavaScript数字和字符串转换示例
2014/03/26 Javascript
jquery实现的一个简单进度条效果实例
2014/05/12 Javascript
jQuery实现首页顶部可伸缩广告特效代码
2015/04/15 Javascript
JavaScript实现上下浮动的窗口效果代码
2015/10/12 Javascript
实例讲解jquery与json的结合
2016/01/07 Javascript
JavaScript头像上传插件源码分享
2016/03/29 Javascript
移动端web滚动分页的实现方法
2017/05/05 Javascript
Node.JS利用PhantomJs抓取网页入门教程
2017/05/19 Javascript
JS实现table表格固定表头且表头随横向滚动而滚动
2017/10/26 Javascript
Vue中keep-alive组件作用详解
2020/02/04 Javascript
详解python进行mp3格式判断
2016/12/23 Python
Python wxPython库Core组件BoxSizer用法示例
2018/09/03 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
Python OpenCV 使用滑动条来调整函数参数的方法
2019/07/08 Python
使用Python将Exception异常错误堆栈信息写入日志文件
2020/04/08 Python
python对批量WAV音频进行等长分割的方法实现
2020/09/25 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
介绍一下XMLHttpRequest对象的常用方法和属性
2013/05/24 面试题
建筑公司文秘岗位职责
2013/11/29 职场文书
银行实习生的自我评价
2013/12/09 职场文书
法人授权委托书格式
2014/04/08 职场文书
师范生求职信
2014/06/14 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
在职员工证明书
2014/09/19 职场文书
2015年学校教务处工作总结
2015/05/11 职场文书
pytorch MSELoss计算平均的实现方法
2021/05/12 Python