关于mongodb:Yii RBAC使用户自己更新个人资料

Yii RBAC make Users update profile by himself

我正在尝试使用mongodbauthmanager进行此操作。我在Usage部分中逐步进行操作,但最终我得到了PHP警告:偏移量类型非法。我已经在克隆到SO之前在Yii Extension上发布了此问题:

请告诉我怎么了?

1 //配置

1
2
3
4
 'authManager'=>array(
    'class'         =>'CMongoDbAuthManager',
    'showErrors'    => true,
  ),

2 //在db

中创建身份验证项

1
2
3
4
5
6
7
8
9
$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中的结果
结果进入数据库http://i.minus.com/iIpXoBlDxaEfo.png

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

1
2
3
4
5
6
7
8
9
10
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 //出现错误:

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

解决的问题

根据@Willem Renzema的答案,我解决了我的问题。现在,我在这里更新,希望它对有人遇到此错误有用。

0 //首先,使用defaultRoles

配置authManager

1
2
3
4
5
   '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

1
2
3
4
5
6
7
8
9
10
11
12
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将由checkAccess中的eval()运行)

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

3 //和用户检查访问授权

1
2
3
4
5
6
7
8
9
10
11
12
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


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

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

现在,CWebUsercheckAccess实现调用了CPHPAuthManager的实现,在这里您遇到了使用非法偏移量类型的问题。

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

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

您在扩展页面上发布的堆栈跟踪显示以下行给出了问题:

1
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的第二个参数时遇到的新错误揭示了其他内容。

因为第二个参数实际上是bizRule中出现的$params数组,所以它应该是。根据错误消息,这意味着Yii::app()->user->id返回一个mondoId类型的对象。

我不熟悉这种类型的对象,所以抬起头来:

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

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

示例:

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

根据您的UserIdentity类中的内容,您的确切代码将有所不同。

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

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