Cannot Enable Authentication From Db

Hello,

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:

  1. 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;

	}

 

  1. 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?

Thank you in advance for your time and support!

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.

Hi

You can log informations using yii::log() to trace what’s happening (or/and use xdebug) To understand what’s happening.


Your problem is in CUserIdentity, I suppose.


 else if (!$user->validatePassword($this->password))

                        $this->errorCode=self::ERROR_PASSWORD_INVALID;



What is $this->password ? It’s a CuserIdenty property. What you want to check is $user->password


 else if (!$user->validatePassword($user->password))

                        $this->errorCode=self::ERROR_PASSWORD_INVALID;



I’m not sure, I hav’nt test. Hope it helps …

Hello Trejder,

Thank you very much for your reply and I am sorry if I did not provide enough details about my issue.

In all cases I was getting the error message that the username or password is incorrect which was not helping much.

I kept on searching and came across another solution using md5 which works. The code is the following:




class UserIdentity extends CUserIdentity

{

	private $_id;


	public function authenticate()

	{ 

		$user = Account::model()->findByAttributes( array( 'username' => $this->username));

		if ($user===null) {

			$this->errorCode=self::ERROR_USERNAME_INVALID;

		} 

		else if($user->password !== md5($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;

	}


	public function getId()

	{

		return $this->_id;

	}


}



The code is similar to the initial one with only two differences.


$user=Account::model()->find('LOWER(username)=?',array(strtolower($this->username)));



and this


else if (!$user->validatePassword($this->password))

I was trying to figure out which one was causing the issue but I didn’t manage to find out. Do you have any clue?

Anyway, the issue is solved now and I hope the above code that I used will help others with the same problem.

Thank you once again Trejder

Hello seb7,

I just saw your reply.

Thank you for your feedback. I tried your solution (in the initial code) by replacing $this->password with $user->password but it still did not work.

I’ll stick to the solution I found and which I mentioned above.

Thank you also for the tip about using yii::log(). I have been using CWebLogRoute but it hadn’t been much of a help.

[/size]

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().

oops. Ok. sorry, read to fast.

[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.

Ah! I missed out last sentence from your previous post, where you wrote, that your problem is already solved.

So my entire previous post (with debugging using die()) is useless…

Hello,

Thank you both for your contribution.

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…

Anyway…thanks once again :)