Domanda

I'm trying to do this with mongodbauthmanager. I'm follow step by step in Usage section but finally i'm getting PHP warning: Illegal offset type. I had posted this question at Yii Extension before clone to SO:

Please tell me what is wrong?

1// Config

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

2// Create auth items in db

$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();

and here is result in db result in db http://i.minus.com/iIpXoBlDxaEfo.png

**3// Checking access in controller ** - UPDATE CODE AND ERROR

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// Getting error:

Fatal error : Cannot use object of type MongoId as array in F:\Data\03. Lab\www\yii\framework\web\auth\CAuthManager.php(150) : eval()'d code on line 1

RESOLVED PROBLEM

Base-on the answer of @Willem Renzema, I resolve my problem. Now, I update here and hope it useful for someone have this error.

0// First, config authManager with defaultRoles

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

1// Fix save id in UserIdentity class

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

2// Fix $bizrule in authe items ($bizrule will run by eval() in checkAccess)

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

3// And user 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// Done, now we can use checkAccess :D

È stato utile?

Soluzione

First off, your original use of checkAccess was correct. Using Yii::app()->user->checkAccess() you are using the following definition:

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

Now, CWebUser's implementation of checkAccess calls CPHPAuthManager's implementation, which is where you encountered your problem with an illegal offset type.

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

An Illegal offset type means you are attempting to access an array element by specifying its key (also known as: offset) with a value that doesn't work as a key. This could be another array, an object, null, or possibly something else.

Your stack trace posted on the extensions page reveals that the following line gives the problem:

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

So we have two possibilities for the illegal offset: $userId and $itemName.

Since $itemName is clearly a string, the problem must be with $userId.

(As a side note, the fact that your stack trace revealed surrounding code of this error also revealed that, at least for CPHPAuthManager, you are using a version of Yii that is prior to 1.1.11. Observe that lines 73 and 74 of https://github.com/yiisoft/yii/blob/1.1.11/framework/web/auth/CPhpAuthManager.php do not exist in your file's code.)

At this point I would have guessed that the problem is that the specified user is not logged in, and so Yii::app()->user->id is returning null. However, the new error you encountered when placing Yii::app()->user->id as the 2nd parameter of checkAccess reveals something else.

Since the 2nd parameter is in fact what should be the $params array that appears in your bizRule. Based on the error message, this means that Yii::app()->user->id is returning a mondoId type object.

I was unfamiliar with this type of object, so looked it up:

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

Long story short, you need to force Yii::app()->user->id to return the string value equivalent of this mondoId object. This likely set in your UserIdentity class in the components folder. To force it to be a string, simply place (string) to force a type conversion.

Example:

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

Your exact code will vary, based on what is in your UserIdentity class.

Then, restore your checkAccess to the signature you had before, and it should eliminate the Illegal offset error you encountered originally.

Note however that I have not used this extension, and while performing the following actions should fix this issue, it may cause new issues if the extension relies on the fact that Yii::app()->user->id is a mondoId object, and not a string.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top