Я пытаюсь создать сайт с помощью Yii и оказался в ситуации, требующей некоторых разъяснений по метафоре управления доступом в Yii. В частности, можно переопределить метод accessRules в CController
.
<Сильный> Необходимое условие:
Вот код, созданный по умолчанию Gii, очень похожий на документация :
public function accessRules()
{
return array(
array('allow', //allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('*'),
),
array('allow',//allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('@'),
),
array('allow',//allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'roles'=> array('admin'),
),
array('deny', //deny all users
'users'=>array('*'),
),
);
}
Вопрос:
Для меня неясно, есть ли , почему нам нужно определять правила доступа для разных пользователей и групп и разные действия вместо проверки прав только одного текущего пользователя и действия? - здесь выделен курсивом, мой главный вопрос подчеркнут, на всякий случай он может не так понят для читателей (авторы ответов).
Этот код выполняется в контексте конкретного запроса, для которого конкретный контроллер
, конкретный action
и конкретный пользователь
) уже известный . Если, например, пользователь является гостем, я не вижу причин для определения правил для роли «admin» или для аутентифицированных пользователей.
<Сильный> Обоснование:
После некоторой разработки я подошел к следующей реализации:
public function accessRules()
{
return array(
array(Yii::app()->user->hasRights()?'allow':'deny'),
);
}
где hasRights
- это простой пользовательский метод, добавленный в потомок CWebUser
:
class WebUser extends CWebUser
{
private $ACL =//ACL example
array('user' =>//controller id
array('index' => User::AC_MODERATOR,//action ids
'view' => User::AC_MODERATOR,
'create' => User::AC_MODERATOR,
'update' => User::AC_ADMIN,
'delete' => User::AC_ADMIN,
'admin' => User::AC_ADMIN),
//...
);
public function hasRights()
{
return (Yii::app()->user->getState('accessRights') >=
$this->ACL[Yii::app()->controller->id][Yii::app()->controller->action->id]);
}
}
Как вы можете видеть, hasRights
использует текущие пользовательские «права» (как обычно, чтение из базы данных), текущий контроллер и действие для вычисления одного логического кода true
или false
code> значение как решение о доступе.
Что не так с этим подходом? Почему Yii не использует что-то простое по умолчанию?
Генерируемый Gii accessRules
выше не только выглядит чрезмерно, но также подразумевает, что правила доступа разбросаны среди многих контроллеров. В моем подходе используется одиночный и компактный ACL.