1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function filters ( ) { return [ 'accessControl' , ]; } function accessRules ( ) { return [ [ 'allow' , 'action' => ['admin' ], 'roles' => ['staff' , 'devel' ], ], [ 'deny' , 'users' => ['*' ], ], ]; }
在用户表中新增一列,列名 roles。建立相应的模型。在这里它将被命名为 “User”。
当添加用户可以给他们分配角色 “管理员”,“用户”,“员工”等等。
在文件 protected/components/UserIdentity.php 添加如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class UserIdentity extends CUserIdentity { private $id ; public function authenticate ( ) { $record = User ::model ()->findByAttributes (['email' => $this ->username]); if (null === $record ) { $this ->errorCode = self ::ERROR_USERNAME_INVALID ; } else if (md5 ($this ->password) !== $record ->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; } }
重要的一行是
1 $this ->setState ('roles' , $record ->roles);
他给会话增加了用户角色。你可以使用如下代码获取用户角色。
1 Yii:app ()->user->getState ("roles" )
或
在 protected/components 文件夹下修改并创建文件 WebUser.php ,然后重写 checkAccess() 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php class WebUser extends CWebUser { public function checkAccess ($operation , $params = [] ) { if (empty ($this ->id)) { return false ; } $role = $this ->getState ("roles" ); if ('admin' === $role ) { return true ; } return ($operation === $role ); } }
在 checkAccess() 方法中你可以定义自己的逻辑。 确保类可以被yii使用配置文件 “protected/config/main.php” 必须包含以下内容:
1 2 3 4 5 6 'components' => [ 'user' => [ 'class' => 'WebUser' , ], ]
旁注: [CWebUser::checkAccess()] 通常连接yii的验证系统。这里我们使用一个简单的处理角色的系统来替换[CAuthManager] 定义的分级系统。详细教程参加 Role-Based Access Control
在你的 PHP 代码中使用 Yii::app()->user->checkAccess('admin')
来检查当前用户是否有 ‘admin’ 角色。
当用户拥有 “staff” 或 “admin” 角色时,调用 Yii::app()->user->checkAccess("staff")
将会返回 true。
在控制器中你可以使用 accessRules() 中的 “roles” 属性进行过滤。
见下面的例子。 怎样过滤动作 控制器必须包含以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function filters ( ) { return [ 'accessControl' , ]; } function accessRules ( ) { return [ [ 'allow' , 'action' => ['admin' ], 'roles' => ['staff' , 'devel' ], ], [ 'deny' , 'users' => ['*' ], ], ]; }
这里对控制器中的 “admin” 动作进行了限制访问: 只有拥有 “staff” 或 “devel” 角色才可以访问。 像API文档中描述的那样 CAccessRule, “roles” 属性实际上调用的是 Yii::app()->user->checkAccess()
方法。 怎样根据角色显示不同菜单 你只需使用一个基于用户角色的菜单。例如
1 2 3 4 5 6 7 8 9 10 <?php $user = Yii ::app ()->user; $this ->widget ('zii.widgets.CMenu' , [ 'items' => [ ['label' => 'Users' , 'url' => ['/manageUser/admin' ], 'visible' => $user ->checkAcces ('staff' )], ['label' => 'Your Ideas' , 'url' => ['/userarea/ideaList' ], 'visible' => $user ->checkAcces ('normal' )], ['label' => 'Login' , 'url' => ['/site/login' ], 'visible' => $user ->isGuest], ['label' => 'Logout (' . Yii ::app ()->user->name . ')' , 'url' => ['/site/logout' ], 'visible' => !$user ->isGuest], ], ]);
一个通常的需求,用户只能够修改自己的数据。在这种情况下,用户的角色是没有任何意义的:将要修改的数据。 这就是为什么 [CWebUser::checkAccess()] 有一个可选的参数 “$param” 。现在假设我们要检查的是一个用户是否有权更新Post记录的权限。我们可以这样写:
1 2 3 if (Yii ::app ()->user->checkAccess ('normal' , $post )) { }
当然 WebUser::checkAccess()
必须被扩展来使用 “$params” 参数。这将取决于你的应用程序的逻辑。比如, 这可能是非常简单的 $post->userId == $this->id
。