New Account Username And Password Incorrect

Hi all,

Just started learning Yii today. Must say I love everything I’ve seen so far, but I was following the first application tutorial and got users working. The problem is when I create a new user I can never log in. I’ve double-checked the password with the database but I still get bad username / pass. Any suggestions?

Have u checked action login method for verifying password ?

Kindly post your codes of the sitecontroller, loginform and useridentity so that we can check.

SiteController:


<?php


class SiteController extends Controller

{

	/**

	 * Declares class-based actions.

	 */

	public function actions()

	{

		return array(

			// captcha action renders the CAPTCHA image displayed on the contact page

			'captcha'=>array(

				'class'=>'CCaptchaAction',

				'backColor'=>0xFFFFFF,

			),

			// page action renders "static" pages stored under 'protected/views/site/pages'

			// They can be accessed via: index.php?r=site/page&view=FileName

			'page'=>array(

				'class'=>'CViewAction',

			),

		);

	}


	/**

	 * This is the default 'index' action that is invoked

	 * when an action is not explicitly requested by users.

	 */

	public function actionIndex()

	{

		// renders the view file 'protected/views/site/index.php'

		// using the default layout 'protected/views/layouts/main.php'

		$this->render('index');

	}


	/**

	 * This is the action to handle external exceptions.

	 */

	public function actionError()

	{

		if($error=Yii::app()->errorHandler->error)

		{

			if(Yii::app()->request->isAjaxRequest)

				echo $error['message'];

			else

				$this->render('error', $error);

		}

	}


	/**

	 * Displays the contact page

	 */

	public function actionContact()

	{

		$model=new ContactForm;

		if(isset($_POST['ContactForm']))

		{

			$model->attributes=$_POST['ContactForm'];

			if($model->validate())

			{

				$name='=?UTF-8?B?'.base64_encode($model->name).'?=';

				$subject='=?UTF-8?B?'.base64_encode($model->subject).'?=';

				$headers="From: $name <{$model->email}>\r\n".

					"Reply-To: {$model->email}\r\n".

					"MIME-Version: 1.0\r\n".

					"Content-Type: text/plain; charset=UTF-8";


				mail(Yii::app()->params['adminEmail'],$subject,$model->body,$headers);

				Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');

				$this->refresh();

			}

		}

		$this->render('contact',array('model'=>$model));

	}


	/**

	 * Displays the login page

	 */

	public function actionLogin()

	{

		$model=new LoginForm;


		// if it is ajax validation request

		if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}


		// collect user input data

		if(isset($_POST['LoginForm']))

		{

			$model->attributes=$_POST['LoginForm'];

			// validate user input and redirect to the previous page if valid

			if($model->validate() && $model->login())

				$this->redirect(Yii::app()->user->returnUrl);

		}

		// display the login form

		$this->render('login',array('model'=>$model));

	}


	/**

	 * Logs out the current user and redirect to homepage.

	 */

	public function actionLogout()

	{

		Yii::app()->user->logout();

		$this->redirect(Yii::app()->homeUrl);

	}

}

LoginForm:


<?php


/**

 * LoginForm class.

 * LoginForm is the data structure for keeping

 * user login form data. It is used by the 'login' action of 'SiteController'.

 */

class LoginForm extends CFormModel

{

	public $username;

	public $password;

	public $rememberMe;


	private $_identity;


	/**

	 * Declares the validation rules.

	 * The rules state that username and password are required,

	 * and password needs to be authenticated.

	 */

	public function rules()

	{

		return array(

			// username and password are required

			array('username, password', 'required'),

			// rememberMe needs to be a boolean

			array('rememberMe', 'boolean'),

			// password needs to be authenticated

			array('password', 'authenticate'),

		);

	}


	/**

	 * Declares attribute labels.

	 */

	public function attributeLabels()

	{

		return array(

			'rememberMe'=>'Remember me next time',

		);

	}


	/**

	 * Authenticates the password.

	 * This is the 'authenticate' validator as declared in rules().

	 */

	public function authenticate($attribute,$params)

	{

		if(!$this->hasErrors())

		{

			$this->_identity=new UserIdentity($this->username,$this->password);

			if(!$this->_identity->authenticate())

				$this->addError('password','Incorrect username or password.');

		}

	}


	/**

	 * Logs in the user using the given username and password in the model.

	 * @return boolean whether login is successful

	 */

	public function login()

	{

		if($this->_identity===null)

		{

			$this->_identity=new UserIdentity($this->username,$this->password);

			$this->_identity->authenticate();

		}

		if($this->_identity->errorCode===UserIdentity::ERROR_NONE)

		{

			$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days

			Yii::app()->user->login($this->_identity,$duration);

			return true;

		}

		else

			return false;

	}

}



UserIdentity:


<?php


/**

 * UserIdentity represents the data needed to identity a user.

 * It contains the authentication method that checks if the provided

 * data can identity the user.

 */

class UserIdentity extends CUserIdentity

{

	/**

	 * Authenticates a user.

	 * The example implementation makes sure if the username and password

	 * are both 'demo'.

	 * In practical applications, this should be changed to authenticate

	 * against some persistent user identity storage (e.g. database).

	 * @return boolean whether authentication succeeds.

	 */

	public function authenticate()

	{

		$users=array(

			// username => password

			'demo'=>'demo',

			'admin'=>'admin',

		);

		if(!isset($users[$this->username]))

			$this->errorCode=self::ERROR_USERNAME_INVALID;

		elseif($users[$this->username]!==$this->password)

			$this->errorCode=self::ERROR_PASSWORD_INVALID;

		else

			$this->errorCode=self::ERROR_NONE;

		return !$this->errorCode;

	}

}

Try to authenticate with admin/admin or demo/demo

I have verified those do work. I logged in as admin/admin and created my new user account, and then it is that new user account I am not allowed to access. And again I’ve triple-checked the password with the database, and tried different usernames and passwords when creating these accounts. There’s no system in place where I need to verify with an authorization email before first login with an account created by admin is there? I checked my mail and spam and never saw an email but I can’t say with 100% certainty that mail is running on the server.

Look at your UserIdentity class. The values are hard-coded in an array. You need to get them from the database surely?


$users=array(

    // username => password

    'demo'=>'demo',

    'admin'=>'admin',

);

Check your UserIdentity class.

Have a look on sample code-


 class UserIdentity extends CUserIdentity

  {

  	private $_id;

  	const ERROR_STATUS_INACTIVE = 10;

  	//private $email;

  	/**

  	* Authenticates a user using the User data model.

  	* @return boolean whether authentication succeeds.

  	*/

  	public function authenticate()

  	{

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

    	if($user===null)

    	{

      	$this->errorCode=self::ERROR_USERNAME_INVALID;

    	}

    	else 

    	{

      	if($user->password!==$user->encrypt($this->password))

      	{

        	$this->errorCode=self::ERROR_PASSWORD_INVALID;

      	}

      	else

      	{

        	$this->_id = $user->id;

        	if(null===$user->lastvisit)

        	{

          	$lastLogin = time();

        	}

    	

        	else

        	{

          	$lastLogin = strtotime($user->lastvisit);

        	}

        	$this->setState('lastLoginTime', $lastLogin); $this->errorCode=self::ERROR_NONE;

      	}

    	}

    	return !$this->errorCode;

  	}

   

  	public function getId()

  	{

    	return $this->_id;

  	}

  }

Check following function in User model-


 protected function afterValidate()

  {

	parent::afterValidate();

	$this->password = $this->encrypt($this->password);                	

  }

  public function encrypt($value)

  {

	return md5($value);

  }

Code in LoginForm model-




public function authenticate($attribute,$params)

{

 	if(!$this->hasErrors())

	{

			$this->_identity=new UserIdentity($this->email, $this->password);

				

 			if(!$this->_identity->authenticate())

 			{

					if($this->_identity->errorCode === UserIdentity::ERROR_USERNAME_INVALID)

						$this->addError('status','Incorrect email or password');

						

					elseif($this->_identity->errorCode === UserIdentity::ERROR_PASSWORD_INVALID)

						$this->addError('status','Incorrect email or password');

						

					elseif($this->_identity->errorCode === UserIdentity::ERROR_STATUS_INACTIVE)

						$this->addError('status','Please check your email to activate your account');

					else

						$this->addError('password','Incorrect email or password.');          	

     		}

  	}

}


		/**

 		* Logs in the user using the given email and password in the model.

 		* @return boolean whether login is successful

 		*/

		public function login()

		{

			if($this->_identity===null)

			{

				$this->_identity=new UserIdentity($this->email,$this->password);

				$this->_identity->authenticate();

			}

			if($this->_identity->errorCode===UserIdentity::ERROR_NONE)

			{	

				Yii::app()->user->login($this->_identity);

				User::model()->updateByPk($this->_identity->id, array('lastvisit'=>new CDbExpression('NOW()')));

				return true;

			}

			else

				return false;

   			}



Here, I have used email as username and md5 encryption for password. I hope you can fix your issue after reviewing my code.

Thank you very much, that solved it!