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 -
Page 1 of 1
Extending the user object after r66
#2
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.
#3
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.
Therefore, in order to save a sql query, i would have to populate the additional user properties from within Identity::authenticate
Is this the right way to do it?
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?
#4
Posted 12 October 2008 - 08:32 AM
No. Do not access user in identity. Please read the Guide for the example about persisting "title".
#5
Posted 12 October 2008 - 08:56 AM
You are refering to http://www.yiiframew...ide/topics.auth and the following code example right?
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()
{
$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);
}
}
#6
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.
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.
#7
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

#8
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);
}
}
#9
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.
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.
Share this topic:
Page 1 of 1