- 基于 AccessControl 的访问控制,一套最基本的权限控制,能识别登录用户和非登录用户(游客),还可以根据 HTTP 请求类型控制是否有权限访问。
- 基于角色的权限访问控制(Role-Based Access Control),简称 RBAC。(这个后期我们再讲)
很显然我们的需求比较简单,不需要引入 RBAC 这个复杂的权限控制,所以本篇文章主要就是先讲讲 AccessControl 如何使用。
基本用法
在对应的控制器文件中修改如下代码:
use yii\filters\AccessControl;
use yii\web\Controller;
class ColumnController extends Controller
{
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
// 默认只能 GET 方式访问
['allow' => true, 'actions' => ['index', 'view'], 'verbs' => ['GET']],
// 默认只能 POST 方式访问
['allow' => true, 'actions' => [], 'verbs' => ['POST']],
// 登录用户 POST 操作
['allow' => true, 'actions' => [], 'verbs' => ['POST'], 'roles' => ['@']],
// 登录用户才能操作
['allow' => true, 'actions' => ['create',], 'roles' => ['@']],
]
],
];
}
// ....
}
这里我们只用到了 AccessControl 最基本的 三个参数,下面我们分别说明一下参数的含义:
allow
:代表是否有权限访问。这意味着你也可以定制一条不允许访问的访问规则。没有这个参数的时候此条规则被认为是不允许访问规则。actions
:指定规则匹配的操作,是一个 Action ID 的数组。区分大小写的。如果此选项为空或未设置,则意味着该规则适用于所有操作。roles
:指定此规则适用的用户角色。如果此选项为空或未设置,则意味着该规则适用于所有角色。框架自带有两个特殊的角色:?
:匹配游客@
:匹配已经登录的用户高级用法
only
和verbs
的用法use yii\filters\AccessControl; use yii\web\Controller; class SiteController extends Controller { /** * @inheritdoc */ public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'only' => ['logout', 'signup'], 'rules' => [ ['actions' => ['signup'], 'allow' => true, 'roles' => ['?']], ['actions' => ['logout'], 'allow' => true, 'roles' => ['@']], ], ], 'verbs' => [ 'class' => VerbFilter::className(), 'actions' => ['logout' => ['post']], ], ]; } }
only
:这个参数的值为一个 Action ID 的数组,上面的示例表示 SiteController 只控制 logout 和 signup 两个的访问操作,其他的操作不进行访问控制。verbs
:用来限制操作的请求类型,最常用的就是delete
操作了,必须是 POST 操作类型。
AccessControl rules 的其他参数
controllers
: 一个 Controller ID 的数组,颗粒度只能控制到 Controller 级别,不细化到 Action 级别。我的理解是如果前台把 AccessControl 放在统一一个地方配置的话,这个还是有点用的。不然真不知道使用场景。具体使用看源码的注释。roleParams
: 这个要配合 RBAC 判断一个角色是否有权限的时候使用,值为角色的参数。具体使用看源码的注释。ips
:这个参数可以设置根据 IP 判断是否是否有权限。值为数组,可以使用通配符,例如:’192.168.*’。用的频率不高。matchCallback
:通过回调函数,判断是否有权限使用。使用示例:use yii\filters\AccessControl; use yii\web\Controller; class SiteController extends Controller { /** * @inheritdoc */ public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'rules' => [ [ 'allow' => true, 'actions' => ['index'], 'matchCallback' => function ($rule, $action) { // 12月28号才可以访问 /site/index 方法 return date('m-d') === '12-28'; } ], ], ] ]; } }
denyCallback
: 当不设置allow
或者allow
设置为false
的时候,会出发这个回调函数,如果如需要你可以通过这个回调函数执行一些业务。使用示例:use yii\filters\AccessControl; use yii\web\Controller; class ColumnController extends Controller { /** * @inheritdoc */ public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'rules' => [ [ 'allow' => false, 'actions' => ['index'], 'denyCallback' => function ($rule, $action) { // 访问 /column/index 页面的时候,跳转到 /site/index 并提示没有权限 Yii::$app->session->setFlash('warning', '您没有权限'); return $this->redirect(['site/index']); } ], ], ] ]; } }
统一处理,游客不允许访问后台系统
管理后台游客一般都是不允许访问除了登录以为的地址,我又不想一个一个控制器写行为,也不想写一个基类的控制器,然后再基类里面写行为,那么如何优雅的实现这个需求呢?现在你只需要两步就能优雅的实现:
一、修改后台配置文件 backend/config/main.php,添加三行代码:return [ // ... code 'components' => [ // ... code ], 'as access' => [ 'class' => 'common\components\AccessControl', ], // ... code ];
二、添加 common\components\AccessControl.php 文件:
<?php namespace common\components; use Yii; use yii\web\User; use yii\di\Instance; class AccessControl extends \yii\base\ActionFilter { /** * @var User User for check access. */ private $_user = 'user'; /** * Get user * @return User */ public function getUser() { if (!$this->_user instanceof User) { $this->_user = Instance::ensure($this->_user, User::className()); } return $this->_user; } /** * Set user * @param User|string $user */ public function setUser($user) { $this->_user = $user; } /** * @inheritdoc */ public function beforeAction($action) { $user = $this->getUser(); return $this->denyAccess($user); } /** * @param User|string $user * @return bool */ protected function denyAccess($user) { if ($user->getIsGuest()) { $user->loginRequired(); } return true; } /** * @param \yii\base\Action $action * @return bool */ protected function isActive($action) { $uniqueId = $action->getUniqueId(); if ($uniqueId === Yii::$app->getErrorHandler()->errorAction) { return false; } $user = $this->getUser(); if ($user->getIsGuest() && is_array($user->loginUrl) && isset($user->loginUrl[0]) && $uniqueId === trim($user->loginUrl[0], '/')) { return false; } return true; } }
as xxx
是 Yii2 里面的高级用法,以后有机会再聊吧,你现在知道可以这样用就行了。总结
这一篇文章我们主要是讲了在 Yii2 中是如何实现访问控制的,通过几个简单的实例,简述了最常用的功能,并且还简单罗列了一些不常用的参数含义。
除此之外我们还列举了后台最常用的访问控制场景。参考链接
- Class yii\filters\AccessRule