Yii Framework Forum: Extending the user object after r66 - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

Extending the user object after r66 Rate Topic: -----

#1 User is offline   rojaro 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 06-October 08
  • Location:hamburg.de

Posted 12 October 2008 - 06:39 AM

Hi qiang,

i am a little bit troubled with your r66 checkin regarding the removal of the WebUser.php class. I previously extended it with methods like this one: [tt]Yii::app()->user->hasAvatar()[/tt]. Now i am not sure where to implement these methods.

Greetings from Hamburg / Germany
- rojaro -
0

#2 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,895
  • Joined: 04-October 08
  • Location:DC, USA

Posted 12 October 2008 - 06:52 AM

it is not removed. U can still do what u r doing now. The change is about decoupling authentication from CWebUser.
0

#3 User is offline   rojaro 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 06-October 08
  • Location:hamburg.de

Posted 12 October 2008 - 08:25 AM

But exactly this decoupling is what really confuses me.

In PRADO used to extend the user object to also carry information like the users email address, his numeric database Id as primary identifier so i could do stuff like $this->Application->User->Id (which would return the database id), $this->Application->User->Username, $this->Application->User->Email,  etc. As all that stuff is stored in the session, i dont have to reload the user record foreach request where i have to display user specific details.

Since the authentication is now done in Identity::authenticate() method, the user record is also loaded there.
public function authenticate()
{
    if(User::model()->findByAttributes(array('LoginName'=>$this->username,'Password'=>hash('sha256', $this->password))) !== null)
    $this->errorCode=self::ERROR_NONE;
else
    $this->errorCode=self::ERROR_PASSWORD_INVALID;
return !$this->errorCode;
}


Therefore, in order to save a sql query, i would have to populate the additional user properties from within Identity::authenticate
public function authenticate()
{
    if(($userRecord = User::model()->findByAttributes(array('LoginName'=>$this->username,'Password'=>hash('sha256',$this->password)))) !== null)
    {
        $user = Yii::app()->getUser();
        $user->setId($userRecord->Id);
        $user->setUserName($userRecord->LoginName);
        $user->setNickName($userRecord->NickName);
        $user->setEmail($userRecord->Email);
        $user->setAvatar($userRecord->AvatarId);
        // many more properties ...
        $this->errorCode=self::ERROR_NONE;
    }
    else
        $this->errorCode=self::ERROR_PASSWORD_INVALID;
    return !$this->errorCode;
}


Is this the right way to do it?
0

#4 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,895
  • Joined: 04-October 08
  • Location:DC, USA

Posted 12 October 2008 - 08:32 AM

No. Do not access user in identity. Please read the Guide for the example about persisting "title".
0

#5 User is offline   rojaro 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 06-October 08
  • Location:hamburg.de

Posted 12 October 2008 - 08:56 AM

You are refering to http://www.yiiframew...ide/topics.auth and the following code example right?
class Identity extends CIdentity
{
    public function authenticate()
    {
        $valid=User::model()->findByAttributes(array(
            'username'=>$this->username,
            'password'=>md5($this->password))) !== null;
        if(!$valid)
        {
            $this->errorCode=self::ERROR_UNKNOWN;
            $this->errorMessage='some message';
        }
        return $valid;
    }

    public function getTitle()
    {
        return $this->getState('title');
    }

    public function setTitle($value)
    {
        $this->setState('title',$value);
    }
}


I see you've defined a getter and a setter, but the setter is never called. Shouldn't this example look like this instead?
class Identity extends CIdentity
{
public function authenticate()
{
if(($userRecord=User::model()->findByAttributes(array('LoginName'=>$this->username)))===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
elseif($userRecord->Password!=hash('sha256', $this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->errorCode=self::ERROR_NONE;
$this->setTitle($userRecord->Title);
}
return $this->errorCode;
}

public function getTitle()
{
return $this->getState('title');
}

public function setTitle($value)
{
$this->setState('title',$value);
}
}

0

#6 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,895
  • Joined: 04-October 08
  • Location:DC, USA

Posted 12 October 2008 - 08:58 AM

You're right. I will fix it.
In general, do not access Yii::app()->user in identity code. The user object will fetch the needed data from identity automatically when you do Yii::app()->user->login(). You may also use "yiic webapp" to generate a new app to see how this works.
0

#7 User is offline   rojaro 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 06-October 08
  • Location:hamburg.de

Posted 12 October 2008 - 09:03 AM

Quote

You may also use "yiic webapp" to generate a new app to see how this works.

I did, but since the generated "demo" doesn't use any databases and relies on a hard coded user name and pasword, it isn't really useful as example when you have to deal with a database instead ;)
0

#8 User is offline   rojaro 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 06-October 08
  • Location:hamburg.de

Posted 12 October 2008 - 09:05 AM

I just simplified that example a little bit ...
class Identity extends CIdentity
{
public function authenticate()
{
if(($userRecord=User::model()->findByAttributes(array('LoginName'=>$this->username)))===null)
return $this->errorCode=self::ERROR_USERNAME_INVALID;

if($userRecord->Password!=hash('sha256', $this->password))
return $this->errorCode=self::ERROR_PASSWORD_INVALID;

$this->setTitle($userRecord->Title)
return $this->errorCode=self::ERROR_NONE;
}

public function getTitle()
{
return $this->getState('title');
}

public function setTitle($value)
{
$this->setState('title',$value);
}
}

0

#9 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,895
  • Joined: 04-October 08
  • Location:DC, USA

Posted 12 October 2008 - 09:11 AM

Thanks. I just did the similar thing.
Hope this new identity feature is more flexible than previous.
We can now create various identity classes such as OpenID, LDAP, and reuse them easily.
0

#10 User is offline   rojaro 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 06-October 08
  • Location:hamburg.de

Posted 12 October 2008 - 10:10 AM

Looks good to me, now that i finally got it working ;D
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users