I am trying to setup user authentication from the database but I have not managed to be successful.
The usernames and passwords are stored in a database table called "account". The form that hashes the password using md5 works properly.
I have taken the following steps:
In the Account.php model I have added the following code:
protected function afterValidate()
{
parent::afterValidate();
if (!$this->hasErrors())
$this->password = $this->hashPassword($this->password);
}
public function hashPassword($password)
{
return md5($password);
}
public function validatePassword($password)
{
return $this->hashPassword($password)===$this->password;
}
This is the code inside the UserIdentity.php
<?php
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user=Account::model()->find('LOWER(username)=?',array(strtolower($this->username)));
if ($user===null)
{
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if (!$user->validatePassword($this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id=$user->id;
$this->username=$user->username;
$this->errorCode==self::ERROR_NONE;
}
return $this->errorCode==self::ERROR_NONE;
}
public function getId()
{
return $this->_id;
}
}
I have tried repeatedly to make it work but I have not been successful. I have tried many solutions from wikis, forum, book, other resources, but I have not managed to login successfully.
I have also tried to use the hashed password as text inside the password field but it did not work. I spent all day on this and I am desperate…
Am I missing any step or am I doing something wrong?
Does anyone have a clue on how to enable authentication from the database?
It seems, that you’ve copied exactly or nearly exactly the same code as in auto-generated base Yii application. Where it works for sure.
What exactly do you mean by unsuccessful? You login with login and password, you know is OK, but you’re not getting logged-in? You see some error? Something else happens?
[size=“2”]Provide more details! [/size]Copy error text here. We can’t help you without deeper knowledge of your problem.
CUserIdentity (or any class that extends it) is actually user identity (data), so using $this->password is obligatory.
So, in this context, $this represent data provided by user in login form and $user represents data (model) taken from DB. I don’t think you would like to validate password, that is already stored in DB, right? :]
Call me old-fashioned, but I don’t like all this stuff with Yii:log(). I know, it is more professional (as well as using XDebug), but my experience (let’s called it war experience! :]) proved me, that if everything else fails, going back to old, good die() and print_r() often brings light to ultimate darkness! :]
I suggest you follow this (my) way. Put print_r() wherever you can, to make yourself sure, that your authentication process ever get’s that far and to see some data dumps, a possible source of your problems.
I would change your authenticate() function to this form:
public function authenticate()
{
echo('<pre>Great! We at least managed to get to authenticate()!</pre>');
$user = Account::model()->findByAttributes( array( 'username' => $this->username));
echo('<pre>$model = '.print_r($model, TRUE).'</pre>');
if ($user===null)
{
echo('<pre>Oh, snap! User is NULL!</pre>');
die();
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($user->password !== md5($this->password))
{
echo('<pre>Oh, snap! Password is WRONG!</pre>');
echo('<pre>$this->password (provided) = '.print_r($this->password, TRUE).'</pre>');
echo('<pre>$user->password (from DB) = '.print_r($user->password, TRUE).'</pre>');
die();
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
echo('<pre>Oh, snap! Somehow, we managed to pass authentication!</pre>');
die();
$this->_id=$user->id;
$this->username=$user->username;
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
and carefully read the results.
If this bring you no clue, what is wrong, then reply hear and paste everything you’ll see on your screen until execution of your application is hold by die().
[quote name=‘Trejder’]Call me old-fashioned, but I don’t like all this stuff with Yii:log(). I know, it is more professional (as well as using XDebug), but my experience (let’s called it war experience! :]) proved me, that if everything else fails, going back to old, good die() and print_r() often brings light to ultimate darkness! :]
[/quote]
So I’ll call you old-fashioned. I used yii::log at different levels, one for debuging (in dev mode and production mode (when it seems problems happens or just when launching something new), and one just to log errors. That’s very usefull and can be used in production. No code change except, changing the logger params is very handy. But that’s not the subject.
I had activated logging in the main configuration file but I didn’t manage to get any help from there. I had also used ‘echo’ inside the if statements (without the die() though) but I could still not figure out what was the problem.
I am quite new to Yii and object oriented programming so sometimes it’s hard to realise what I am missing…