深入解析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 insert语法详解
Jun 07 PHP
php adodb操作mysql数据库
Mar 19 PHP
Codeigniter实现发送带附件的邮件
Mar 19 PHP
PHP使用flock实现文件加锁的方法
Jul 01 PHP
PHP封装的Twitter访问类实例
Jul 18 PHP
Smarty使用自定义资源的方法
Aug 08 PHP
PHP使用Pear发送邮件(Windows环境)
Jan 05 PHP
smarty学习笔记之常见代码段用法总结
Mar 19 PHP
java模拟PHP的pack和unpack类
Apr 13 PHP
thinkphp实现分页显示功能
Dec 03 PHP
使用PHP+MySql实现微信投票功能实例代码
Sep 29 PHP
基于Laravel-admin 后台的自定义页面用法详解
Sep 30 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
php循环创建目录示例分享(php创建多级目录)
2014/03/04 PHP
高性能PHP框架Symfony2经典入门教程
2014/07/08 PHP
yii使用activeFileField控件实现上传文件与图片的方法
2015/12/28 PHP
XML的代替者----JSON
2007/07/21 Javascript
js innerHTML 改变div内容的方法
2013/08/03 Javascript
JS在IE下缺少标识符的错误
2014/07/23 Javascript
EasyUI实现二级页面的内容勾选的方法
2015/03/01 Javascript
JavaScript学习笔记之数组的增、删、改、查
2016/03/23 Javascript
谈谈因Vue.js引发关于getter和setter的思考
2016/12/02 Javascript
如何正确理解javascript的模块化
2017/03/02 Javascript
利用js的闭包原理做对象封装及调用方法
2017/04/07 Javascript
浅谈NodeJs之数据库异常处理
2017/10/25 NodeJs
基于vue-video-player自定义播放器的方法
2018/03/21 Javascript
Vue filter介绍及详细使用
2018/04/04 Javascript
JavaScript实现无限级递归树的示例代码
2019/03/29 Javascript
详解vue微信网页授权最终解决方案
2019/06/16 Javascript
jQuery实现容器间的元素拖拽功能
2020/12/01 jQuery
python计算书页码的统计数字问题实例
2014/09/26 Python
wxpython中自定义事件的实现与使用方法分析
2016/07/21 Python
Python Paramiko模块的安装与使用详解
2016/11/18 Python
简单谈谈Python中的几种常见的数据类型
2017/02/10 Python
virtualenv实现多个版本Python共存
2017/08/21 Python
python里使用正则表达式的组嵌套实例详解
2017/10/24 Python
python pandas 如何替换某列的一个值
2018/06/09 Python
Python OpenCV处理图像之图像像素点操作
2018/07/10 Python
浅述python中深浅拷贝原理
2018/09/18 Python
python绘制简单彩虹图
2018/11/19 Python
Python Subprocess模块原理及实例
2019/08/26 Python
python操作ini类型配置文件的实例教程
2020/10/30 Python
苹果音乐订阅:Apple Music
2018/08/02 全球购物
写自荐信有哪些不宜?
2013/10/17 职场文书
40岁生日感言
2014/02/15 职场文书
扩大国家免疫规划实施方案
2014/03/21 职场文书
意向协议书范本
2014/04/23 职场文书
mysql幻读详解实例以及解决办法
2022/06/16 MySQL
Linux服务器离线安装 nginx的详细步骤
2022/06/16 Servers