Yii使用filter进行访问控制

来源:互联网 发布:防沉迷ipad软件 编辑:程序博客网 时间:2024/05/17 05:59
Yii使用filter进行访问控制 
作者:zccst 

在Controller.php 

注:filters是yii的CController.php中定义的方法,而Controller.php是继承CController.php的。此处,相当于覆盖父类中的filters方法。而所有的XXController.php又继承自Controller.php,显然都可以定义authlessActions()方法覆盖父类中相应方法。 
Php代码  收藏代码
  1. public function filterAccessAuth($filterChain) {  
  2.         if(Yii::app()->user->getIsGuest() && !in_array($this->getAction()->getId(), $this->authlessActions())) {  
  3.             Yii::app()->user->setFlash("info""请先登录");  
  4.             Yii::app()->user->loginRequired();  //封装了Yii::app()->user->loginUrl  
  5.         }  
  6.         elseif(!in_array($this->getAction()->getId(), $this->authlessActions()) && $this->current_user && $this->current_user->isPasswordExpired()) {  
  7.             $this->user->setFlash('error'"你的密码已经过期,超过: " . Yii::app()->params['user_pwd_max_expire_day'] . "天没有修改,请修改密码");  
  8.             $this->redirect($this->createUrl("/account/profile"));  
  9.         }  
  10.           
  11.         if(!in_array($this->getAction()->getId(), $this->authlessActions()) && $this->current_user && $this->current_user->hi_id == NULL) {  
  12.             $target_url = $this->createUrl('account/profile');  
  13.             $this->user->setFlash('info'"你还没有设置Hi,请尽快到" . "<a href=\"$target_url\">  账号设置  </a>" . "添加!");    
  14.         }  
  15.   
  16.         $filterChain->run();  
  17.     }  
  18.   
  19.     public function filters() {  
  20.         return array(  
  21.             'accessAuth',  
  22.         );  
  23.     }  
  24.   
  25.     public function authlessActions() {  
  26.         return array();  
  27.     }  

批注1:yii中使用filter规则。 
For method-based filters, a method named 'filterXYZ($filterChain)' in the controller class will be executed, where 'XYZ' stands for the filter name as specified in filters(). Note, inside the filter method, you must call $filterChain->run() if the action should be executed. Otherwise, the filtering process would stop at this filter. 





批注2:另一种用法(隐式用法) 
在1.1.7中,public function filters() { 
return array( 
'accessControl', 
); 

也即accessControl对应下面这个方法 
public void filterAccessControl(CFilterChain $filterChain) 

The filter method for 'accessControl' filter. The filter method for 'accessControl' filter. This filter is a wrapper of CAccessControlFilter. To use this filter, you must override accessRules method. 
Php代码  收藏代码
  1. class PostController extends CController  
  2. {  
  3.     ......  
  4.     public function accessRules()  
  5.     {  
  6.         return array(  
  7.             rray('deny',  
  8.                 'actions'=>array('create''edit'),  
  9.                 'users'=>array('?'),  
  10.                 ),  
  11.             array('allow',  
  12.                 'actions'=>array('delete'),  
  13.                 'roles'=>array('admin'),  
  14.             ),  
  15.             array('deny',  
  16.                 'actions'=>array('delete'),  
  17.                 'users'=>array('*'),  
  18.             ),  
  19.         );  
  20.     }  
  21. }  

所以不难看出filter至少有两种类型,一种是accessAuth,另一种是accessControl。 



批注3:当用户访问index.php?r=site/login 

首先,映射到SiteController.php中 
而在SiteController.php中,覆盖了Controller.php的public function authlessActions()方法,不再是空数组, 
而是return array('login', 'logout', 'error', 'page', 'bashJs'); 



批注4:在actionLogin方法里 
Php代码  收藏代码
  1. if(isset($_POST['LoginForm']))  
  2. {  
  3.     $model->attributes=$_POST['LoginForm'];  
  4.     // validate user input and redirect to the previous page if valid  
  5.     if($model->validate() && $model->login()) {  
  6.         //初始化前,先初始化父类Controller.php的成员变量和成员函数。  
  7.         $this->init();  
  8.   
  9.         // 检查上次密码修改时间  
  10.         if($this->current_user->isPasswordExpired()) {  
  11.             $this->user->setFlash('error'"密码已经" . Yii::app()->params['user_pwd_max_expire_day'] . "天没有修改过了,请修改密码");    
  12.             $this->redirect($this->createUrl("/account/profile"));  
  13.         }  
  14.           
  15.         // 检查有没有设置Hi  
  16.         if($this->current_user->hi_id == NULL) {  
  17.             $target_url = $this->createUrl('account/profile');  
  18.             $this->user->setFlash('info'"你还没有设置Hi,请尽快到"."<a href=\"$target_url\">  账号设置  </a>"."添加!");    
  19.         }  
  20.   
  21.         $this->redirect(Yii::app()->user->returnUrl);  
  22.     }  
  23. }  

根据最前面的方法in_array($this->getAction()->getId(), $this->authlessActions())可以判断该action是否在不用授权数组中。 

注:查看当前controller和action的ID,是Yii::app()->controller->id;和$this->getAction()->getId(); 
其中,$this->getAction()是一个很大的对象,$this->getAction()->getId()是login。 



批注5:关于未登录前,应该走下面这个逻辑 
Php代码  收藏代码
  1. if(Yii::app()->user->getIsGuest() && !in_array($this->getAction()->getId(), $this->authlessActions())) {  
  2.             Yii::app()->user->setFlash("info""请先登录");  
  3.             Yii::app()->user->loginRequired();  //封装了Yii::app()->user->loginUrl  
  4.         }  

根据yii框架实现机制,发现Yii::app()->user->loginRequired()封装了Yii::app()->user->loginUrl。 
即注释掉改行后,project/不会自动跳转到project/index.php?r=site/login页面。 



最后,如果用户登陆成功后,用户跳转到site/index,而其定义为outsource/index,当OutsourceController.php执行时,又一次执行Controller.php,此时的authlessActions数组为空,则in_array()为false,取反为true。执行检查上次修改密码超过30天和是否已添加Hi。 
0 0
原创粉丝点击