深入解析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 相关文章推荐
第二节 对象模型 [2]
Oct 09 PHP
用PHP实现登陆验证码(类似条行码状)
Oct 09 PHP
php中文本操作的类
Mar 17 PHP
收集的二十一个实用便利的PHP函数代码
Apr 22 PHP
php 数组动态添加实现代码(最土团购系统的价格排序)
Dec 30 PHP
PHP session文件独占锁引起阻塞问题解决方法
May 12 PHP
php 利用socket发送HTTP请求(GET,POST)
Aug 24 PHP
详解PHP数组赋值方法
Nov 07 PHP
YII2 实现多语言配置的方法分享
Jan 11 PHP
php伪静态验证码不显示的解决方案
Sep 26 PHP
PHP 自动加载类原理与用法实例分析
Apr 14 PHP
discuz论坛更换域名,详细文件修改步骤
Dec 09 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笔记之:初探PHPcms模块开发介绍
2013/04/26 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式一图文详解
2019/04/09 PHP
Yii使用EasyWechat实现小程序获取用户的openID的方法
2020/04/29 PHP
javascript引用对象的方法
2007/01/11 Javascript
jQuery(1.3.2) 7行代码搞定跟随屏幕滚动的层
2009/05/21 Javascript
COM中获取JavaScript数组大小的代码
2009/11/22 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
2012/02/27 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
js使用for循环及if语句判断多个一样的name
2014/09/09 Javascript
node.js使用npm 安装插件时提示install Error: ENOENT报错的解决方法
2014/11/20 Javascript
jQuery中;function($,undefined) 前面的分号的用处
2014/12/17 Javascript
js实现文本框中输入文字页面中div层同步获取文本框内容的方法
2015/03/03 Javascript
jQuery.datatables.js插件用法及api实例详解
2016/10/28 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
2017/07/13 Javascript
vue数据控制视图源码解析
2018/03/28 Javascript
swiper在vue项目中loop循环轮播失效的解决方法
2018/09/15 Javascript
Vue创建头部组件示例代码详解
2018/10/23 Javascript
JS实现的点击按钮图片上下滚动效果示例
2019/01/28 Javascript
JS删除String里某个字符的方法
2021/01/06 Javascript
vue实现拖拽的简单案例 不超出可视区域
2019/07/25 Javascript
Python AES加密实例解析
2018/01/18 Python
python基础教程项目三之万能的XML
2018/04/02 Python
Python 字符串与数字输出方法
2018/07/16 Python
英国山地公路自行车商店:Tweeks Cycles
2018/03/16 全球购物
德国药房apodiscounter中文官网:德国排名前三的网上药店
2019/06/03 全球购物
Saks Fifth Avenue澳洲/亚太地区:萨克斯第五大道精品百货店
2019/06/09 全球购物
幼儿园教研活动总结
2014/04/30 职场文书
市场营销战略计划书
2014/05/06 职场文书
地球一小时宣传标语
2014/06/24 职场文书
化学教育专业自荐信
2014/07/04 职场文书
2014年保育员个人工作总结
2014/12/02 职场文书
国家助学金受助感言
2015/08/01 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang
Django基础CBV装饰器和中间件
2022/03/22 Python
SQL Server删除表中的重复数据
2022/05/25 SQL Server