Yii RBAC让用户自己更新个人资料

时间:2013-04-07 09:13:21

标签: mongodb yii authorization yii-extensions rbac

我正在尝试使用mongodbauthmanager执行此操作。我在Usage部分一步一步地遵循,但最后我得到 PHP警告:非法偏移类型。在克隆到SO之前,我在Yii Extension发布了这个问题:

请告诉我有什么问题?

1 //配置

 'authManager'=>array(
    'class'         =>'CMongoDbAuthManager',
    'showErrors'    => true,
  ),

2 //在db

中创建auth项目
$auth = new CMongoDbAuthManager();

$bizRule = 'return Yii::app()->user->id==$params["User"]->_id;';
$auth->createTask('updateSelf', 'update own information', $bizRule);
//I had tried with $auth->createOperation() but they has the same error
$role = $auth->createRole('user');
$role->addChild('updateSelf');

$auth->save();

,这是db的结果 result in db http://i.minus.com/iIpXoBlDxaEfo.png

** 3 //检查控制器中的访问权限** - 更新代码和错误

public function actionUpdate($id)
    {
        $model=$this->loadModel($id);
        $params = array('User'=>$model);
        if (!Yii::app()->user->checkAccess('updateSelf', Yii::app()->user->id,$params) )
        {
            throw new CHttpException(403, 'You are not authorized to perform this action');
        }
//another statement ...
}

4 //获取错误:

致命错误:无法在F:\ Data \ 03中使用MongoId类型的对象作为数组。第1行的Lab \ www \ yii \ framework \ web \ auth \ CAuthManager.php(150): eval()'d 代码

已解决的问题

根据@Willem Renzema的答案,我解决了我的问题。现在,我在这里更新,并希望有人有这个错误。

0 //首先,使用defaultRoles配置authManager

   'authManager'=>array(
        'class'=>'CMongoDbAuthManager',
        'showErrors' => true,
        'defaultRoles'=> array('user'),//important, this line help we don't need assign role for every user manually
    ),

1 //修复UserIdentity类中的保存ID

class UserIdentity extends CUserIdentity
{
    private $_id;
    //...
    public function authenticate()
    {
         //...
         $this->_id = (string)$user->_id;//force $this save _id by string, not MongoId object
         //...
    }
    //...
}

2 //修复认证项目中的$ bizrule ($ bizrule将由eval()中的checkAccess

运行
//use _id as string, not MongoId object
$bizRule = 'return Yii::app()->user->id==(string)$params["User"]->_id;';

3 //用户checkAccess to authorization

public function actionUpdate($id){
        /**
         * @var User $model
         */
        $model=$this->loadModel($id);
        $params = array('User'=>$model);
        if (!Yii::app()->user->checkAccess('updateSelf', $params) )
        {
            throw new CHttpException(403, 'You are not authorized to perform this action');
        }
        //...
}

4 //完成,现在我们可以使用checkAccess:D

1 个答案:

答案 0 :(得分:2)

首先,您对checkAccess的原始使用是正确的。使用Yii::app()->user->checkAccess()您正在使用以下定义:

http://www.yiiframework.com/doc/api/1.1/CWebUser#checkAccess-detail

现在,CWebUser实现了checkAccess调用CPHPAuthManager的实现,这是您遇到非法偏移类型问题的地方。

http://www.yiiframework.com/doc/api/1.1/CPhpAuthManager#checkAccess-detail

Illegal offset type表示您尝试通过使用不作为键的值指定其键(也称为:offset)来访问数组元素。这可能是另一个数组,一个对象,null,或者可能是其他东西。

在扩展程序页面上发布的堆栈跟踪显示以下行显示问题:

if(isset($this->_assignments[$userId][$itemName]))

因此,我们有两种非法偏移的可能性:$userId$itemName

由于$itemName显然是一个字符串,因此问题必须是$userId

(作为旁注,您的堆栈跟踪显示此错误的周围代码的事实也表明,至少对于CPHPAuthManager,您使用的是Yii版本,该版本优先于1.1.11。你文件的代码中不存在https://github.com/yiisoft/yii/blob/1.1.11/framework/web/auth/CPhpAuthManager.php的第73和74行。)

此时我猜测问题是指定的用户没有登录,因此Yii::app()->user->id正在返回null。但是,将Yii::app()->user->id作为checkAccess的第二个参数放置时遇到的新错误会显示其他内容。

由于第二个参数实际上应该是$params中显示的bizRule数组。根据错误消息,这意味着Yii::app()->user->id正在返回mondoId类型对象。

我不熟悉这种类型的物体,所以查了一下:

http://php.net/manual/en/class.mongoid.php

长话短说,您需要强制Yii::app()->user->id返回与此mondoId对象等效的字符串值。这可能设置在UserIdentity文件夹中的components类中。要强制它成为字符串,只需放置(string)以强制进行类型转换。

示例:

$this->_id = (string)$User->_id;

您的确切代码会因UserIdentity课程中的内容而异。

然后,将checkAccess恢复为之前的签名,它应该消除您最初遇到的Illegal offset error

但是请注意,我没有使用此扩展程序,并且在执行以下操作时应该解决此问题,如果扩展程序依赖于Yii::app()->user->idmondoId对象的事实,则可能会导致新问题,而不是字符串。