1

我正在尝试使用mongodbauthmanager来做到这一点。我在Usage部分中一步一步地进行操作,但最后我收到了PHP 警告:非法偏移类型。在克隆到 SO 之前,我已经在Yii Extension上发布了这个问题:

请告诉我有什么问题吗?

1// 配置

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

2// 在数据库中创建身份验证项

$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 结果在 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// 得到错误:

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

已解决的问题

基于 的答案@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()in 中运行checkAccess

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

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

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

4

1 回答 1

2

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

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

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

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

AnIllegal offset type表示您试图通过指定其键(也称为:偏移量)来访问数组元素,该值不能用作键。这可能是另一个数组、一个对象、null 或其他东西。

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

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

所以我们有两种非法偏移的可能性:$userId$itemName

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

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

此时我已经猜到问题是指定用户未登录,因此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对象等效的字符串值。这可能是在您UserIdentitycomponents文件夹中设置的。要强制它为字符串,只需放置(string)强制类型转换。

例子:

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

您的确切代码会有所不同,具体取决于您UserIdentity班级中的内容。

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

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

于 2013-04-08T08:46:40.497 回答