深入解析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 中检查或过滤IP地址的实现代码
Nov 27 PHP
析构函数与php的垃圾回收机制详解
Oct 28 PHP
php根据操作系统转换文件名大小写的方法
Feb 24 PHP
浅析ThinkPHP的模板输出功能
Jul 01 PHP
PHP使用Face++接口开发微信公众平台人脸识别系统的方法
Apr 17 PHP
在Mac OS上编译安装Nginx+PHP+MariaDB开发环境的教程
Feb 23 PHP
Zend Framework教程之模型Model用法简单实例
Mar 04 PHP
2017年最新PHP经典面试题目汇总(上篇)
Mar 17 PHP
PHP基于redis计数器类定义与用法示例
Feb 08 PHP
PHP实现压缩图片尺寸并转为jpg格式的方法示例
May 10 PHP
PHP实现简单计算器小程序
Aug 28 PHP
PHP Swoole异步Redis客户端实现方法示例
Oct 24 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安装问题
2006/10/09 PHP
PHP中输出转义JavaScript代码的实现代码
2011/04/22 PHP
PHP中提问频率最高的11个面试题和答案
2014/09/02 PHP
thinkPHP实现瀑布流的方法
2014/11/29 PHP
javascript 命名空间以提高代码重用性
2008/11/13 Javascript
php图像生成函数之间的区别分析
2012/12/06 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
JS实现两个大数(整数)相乘
2014/04/28 Javascript
node.js读取文件到字符串的方法
2015/06/29 Javascript
jQuery 插件封装的方法
2016/11/16 Javascript
Extjs让combobox写起来简洁又漂亮
2017/01/05 Javascript
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
js实现扫雷小程序的示例代码
2017/09/27 Javascript
angularJs在多个控制器中共享服务数据的方法
2018/09/30 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
python 简单备份文件脚本v1.0的实例
2017/11/06 Python
Python实现将json文件中向量写入Excel的方法
2018/03/26 Python
python3调用百度翻译API实现实时翻译
2018/08/16 Python
使用Scrapy爬取动态数据
2018/10/21 Python
Python socket非阻塞模块应用示例
2019/09/12 Python
PyCharm永久激活方式(推荐)
2020/09/22 Python
Python pandas 列转行操作详解(类似hive中explode方法)
2020/05/18 Python
django在开发中取消外键约束的实现
2020/05/20 Python
python能做哪方面的工作
2020/06/15 Python
django创建css文件夹的具体方法
2020/07/31 Python
学校消防安全制度
2014/01/30 职场文书
父亲的菜园教学反思
2014/02/13 职场文书
小学生光盘行动倡议书
2015/04/28 职场文书
优秀班主任工作总结2015
2015/05/25 职场文书
运动会开幕式致辞
2015/07/29 职场文书
2016年五四青年节校园广播稿
2015/12/17 职场文书
2016年教师师德师风承诺书
2016/03/25 职场文书
详解NodeJS模块化
2021/06/15 NodeJs
JavaScript中MutationObServer监听DOM元素详情
2021/11/27 Javascript
六个好看实用的 HTML + CSS 后台登录入口页面
2022/04/28 HTML / CSS