如果你需要简单的基于角色的访问控制而不是长长的RBAC过程,那么这篇文章非常适合你。让我们直入主题。
在用户表中新增一列,列名roles。建立相应的模型。在这里它将被命名为 “User”。
当添加用户可以给他们分配角色 “管理员”,“用户”,“员工”等等。
在文件protected/components/UserIdentity.php添加如下内容:
class UserIdentity extends CUserIdentity { private $id; public function authenticate() { $record=User::model()->findByAttributes(array('email'=>$this->username)); if($record===null) $this->errorCode=self::ERROR_USERNAME_INVALID; else if($record->password!==md5($this->password)) $this->errorCode=self::ERROR_PASSWORD_INVALID; else { $this->id=$record->id; $this->setState('roles', $record->roles); $this->errorCode=self::ERROR_NONE; } return !$this->errorCode; } public function getId(){ return $this->id; } }
重要的一行是$this->setState('roles', $record->roles);他给会话增加了用户角色。 你可以使用Yii:app()->user->getState("roles")或Yii::app()->user->roles获取用户角色。
在protected/components文件夹下修改并创建文件WebUser.php,然后重写checkAccess()方法。
class WebUser extends CWebUser { /** * Overrides a Yii method that is used for roles in controllers (accessRules). * * @param string $operation Name of the operation required (here, a role). * @param mixed $params (opt) Parameters for this operation, usually the object to access. * @return bool Permission granted? */ public function checkAccess($operation, $params=array()) { if (empty($this->id)) { // Not identified => no rights return false; } $role = $this->getState("roles"); if ($role === 'admin') { return true; // admin role has access to everything } // allow access if the operation request is the current user's role return ($operation === $role); } }
在checkAccess()方法中你可以定义自己的逻辑。
确保类可以被yii使用配置文件 "protected/config/main.php" 必须包含以下内容:
'components' => array( // ... 'user' => array( 'class' => 'WebUser', ),
旁注:
[CWebUser::checkAccess()] 通常连接yii的验证系统。 这里我们使用一个简单的处理角色的系统来替换[CAuthManager] 定义的分级系统。详细教程参加
, “roles” 属性实际上调用的是Yii::app()->user->checkAccess()方法。
你只需使用一个基于用户角色的菜单。例如
$user = Yii::app()->user; // just a convenience to shorten expressions $this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Users', 'url'=>array('/manageUser/admin'), 'visible'=>$user->checkAcces('staff')), array('label'=>'Your Ideas', 'url'=>array('/userarea/ideaList'), 'visible'=>$user->checkAcces('normal')), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>$user->isGuest), array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!$user->isGuest) ), )); ?>
一个通常的需求,用户只能够修改自己的数据。 在这种情况下,用户的角色是没有任何意义的:将要修改的数据。
这就是为什么 [CWebUser::checkAccess()] 有一个可选的参数 "$param" 。现在假设我们要检查的是一个用户是否有权更新Post记录的权限。我们可以这样写:
if (Yii::app()->user->checkAccess('normal', $post)) {
当然WebUser::checkAccess()必须被扩展来使用 "$params" 参数。 这将取决于你的应用程序的逻辑。 比如, 这可能是非常简单的$post->userId == $this->id。