作者:老王
CakePHP的好处就是它把
Web开发中常见的问题都拿出来,并给了一个具体的解决方案,比如说常见的
Ajax,分页,表单验证等等都有很简单的处理方式,当然还有一个老大难问题:权限!对于这个问题,CakePHP给出的答案是Acl组件和Auth组件,更进一步讲,Auth组件是Acl组件的一个封装,实际我们在CakePHP1.2中处理权限,只要使用Auth组件一般就可以了。
Auth组件可以说是现有CakePHP组件里最难使用的了,加上1.2一直没有
官方文档,所以
组件的相关用法只能靠自己看
源代码来理解。
大致来说,使用方式如下:
首先,当然是加载相应的组件了,var $components = array('Auth'),视情况可能还需要加上Acl组件,然后我们就可以在
控制器的beforeFilter()方法中对Auth进行一些初始化设置:
复制内容到剪贴板
代码:
------------------------------------------------
$this->Auth->userModel = 'User';
$this->Auth->fields = array(
'username' => 'username',
'password' => 'password'
);
$this->Auth->userScope = array('User.disabled' => 0);
$this->Auth->autoRedirect = true;
$this->Auth->loginAction = '/users/login';
$this->Auth->loginRedirect = '/users/index';
$this->Auth->authError = 'You are not authorized to access that location.';
$this->Auth->loginError = 'Login failed. Invalid username or password.';
------------------------------------------------这里面包括用户表的表名,用户名和密码的
字段名,和其他一些相关信息等等,实际情况具体要设置哪些视情况而定。
设定好了这些,就面临一个决策问题了!我们的Auth组件到底应该工作在一种什么情况下,在内部使用$this->Auth->authorize来决定,目前,它有如下几个合法值:false, controller, model, actions, crud.下面会依次讲一下他们的含义及用法:
如果设置$this->Auth->authorize = false;就表示你要关闭Auth,比如说我们很多控制器里都进行了权限判断,但是在某个控制器(如:pages)里想让所有的人都有权限访问,就可以在这个特殊的控制器使用这个设置来关闭权限判断。
如果设置$this->Auth->authorize = 'controller';就表示使用基于控制器的权限判断,使用这个设置会要求你的控制器里要有一个名为isAuthorized()的回调方法,并返回true或者false来表示通过权限验证与否。一般可以用在这样的情况:比如后台仅仅要求管理员登录,其他人都拒绝,这样的情况,我们就可以在isAuthorized方法里验证用户的group是否是管理员组,如果是就返回true,否则false,就完成了权限判断。
如果设置$this->Auth->authorize = 'model';就表示使用基于模型的权限判断,也就是说,我们的权限判断里涉及了领域逻辑,因为如果没有涉及领域逻辑的话,使用上一种基于控制器的方式就足够了。在使用这种方式的时候,还要注意一点就是把$this->Auth->objectModel设定为你要进行权限判断的模型,还有一种更简单的方式,就是在设定的时候直接设定为$this->Auth->authorize = array('model'=>'objectToAuthorize'),就可以了(其中:objectToAuthorize是相应模型的名字),此外,模型中要有一个isAuthorized($user)回调方法来判断是否通过了验证。那什么情况下才应该使用基于模型的权限判断呢?或者说什么情况下我们的权限判断才会涉及领域逻辑呢?比如说,在一个CMS里,一篇文章只有评论超过100条,浏览超过10000次,并且是金牌用户发的文章,才有资格被加入到热门文章的候选中,假设我们的CMS里有一个“加入热门文章”的按钮,对于这个操作的权限判断就涉及了领域逻辑,那么这里的领域逻辑是什么呢,就是热门文章的候选条件(评论超过100条,浏览超过10000次,并且是金牌用户发的文章),使用基于模型的权限判断,就可以在模型的isAuthorized($user)方法中完成这个验证过程,可以看出,类似这样的权限判断,如果你使用基于控制器的形式,就很可能会导致你的领域逻辑泄露到控制器中,那样你的模型就不再是完整的了,MVC也就成为了一个摆设。
BTW:你可能觉得类似“评论超过100条,浏览超过10000次,并且是金牌用户发的文章”这样的逻辑太变态了,不过实际情况中,业务逻辑总是很变态的,“逻辑”本身往往是最没有逻辑可言的东西。
以上几种方式,Auth的使用都没有涉及Acl,如果你使用actions或者crud方式,那么就不可避免的要涉及Acl,相应的组件声明也要变为var $components = array('Acl', 'Auth')方式,至于这两种方式下Auth用法我不想再多说了,差不多就是Acl的用法了。
以我个人的看法,用Auth做权限判断的时候,不是必要的话,最好不要把Acl牵扯进来,也就是说,视情况使用基于controller或者基于model的方式。