CAccessRule 的 isUserMatched
protected function isUserMatched($user) { if(empty($this->users)) return true; foreach($this->users as $u) { if($u==='*') return true; elseif($u==='?' && $user->getIsGuest()) return true; elseif($u==='@' && !$user->getIsGuest()) return true; elseif(!strcasecmp($u,$user->getName())) return true; } return false; }
理解:
1.*:代表任何人,返回true;
2.?:代表游客,当__id===null返回true;
3.@:代表非游客,当__id!=null返回true;
4.$u:代表用户名,当__name==$u返回true。
CAccessRule 的 isUserAllowed
public function isUserAllowed($user,$controller,$action,$ip,$verb) { if($this->isActionMatched($action) && $this->isUserMatched($user) && $this->isRoleMatched($user) && $this->isIpMatched($ip) && $this->isVerbMatched($verb) && $this->isControllerMatched($controller) && $this->isExpressionMatched($user)) return $this->allow ? 1 : -1; else return 0; }
理解:
1.不符合匹配时返回0;
2.符合匹配并且是允许时返回1;
3.符合匹配并且是拒绝时返回-1;
CAccessControlFilter 的 preFilter
protected function preFilter($filterChain) { $app=Yii::app(); $request=$app->getRequest(); $user=$app->getUser(); $verb=$request->getRequestType(); $ip=$request->getUserHostAddress(); foreach($this->getRules() as $rule) { if(($allow=$rule->isUserAllowed($user,$filterChain->controller,$filterChain->action,$ip,$verb))>0) // allowed break; elseif($allow<0) // denied { if(isset($rule->deniedCallback)) call_user_func($rule->deniedCallback, $rule); else $this->accessDenied($user,$this->resolveErrorMessage($rule)); return false; } } return true; }
理解:
1.当遇到一个规则返回1时,则不匹配后面的规则,过滤器立即返回true;
2.支持自定义拒绝回调。
Controller
class SiteController extends CController
{
public function filters()
{
return array(
'accessControl', // perform access control for CRUD operations
);
}
public function accessRules()
{
return array(
array('allow', // allow all users to access 'index' and 'view' actions.
'actions'=>array('login'),
'users'=>array('*'),
),
array('allow', // allow authenticated users to access all actions
'users'=>array('@'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
public function deniedCallback()
{
echo '<pre>';
var_dump(func_get_args());
}
public function actionIndex()
{
//TODO
}
public function actionLogin()
{
//TODO
}
}
实践:
1.当访问login时(不论登录状态如何),第一个规则返回1,跳过后两个规则,过滤器立即返回true;
2.当用户未登录时访问index,第一个规则返回0,接着第二个规则非游客返回0,最后第三个规则返回-1,过滤器回调自定义的拒绝回调函数并返回false;
3.当用户未登录时访问index,第一个规则返回0,接着第二个规则非游客返回1,跳过第三个规则,过滤器立即返回true;