[Solved] Problem Login

para master ada yang tau kenapa pada saat melakukan login, jika usernamenya benar dan passwordnya salah masih tetep bisa masuk?

ini UserIdentity.php


<?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;

	}*/

	

	private $_id;

	public $username;

	public $password;

	

	public function authenticate()

	{

		$username = ($this->username);

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

		$pwd = TBLUSR::model()->findByAttributes(array('PASSWORD'=>$this->password));

		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->USR_ID;

			$this->username = $user->USR_NAME;

			$this->password = $user->PASSWORD;

			

			$this->errorCode=self::ERROR_NONE;

		}

		return $this->errorCode==self::ERROR_NONE;

	}

	

	public function getId()

	{

		return $this->_id;

	}

}

Ini SiteController.php


<?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'

		if (Yii::app()->user->isGuest)

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

        else

			$this->render('index');

	}

	

	/**

	 * @return array action filters

	 */

	public function filters()

	{

		return array(

			'accessControl',

		);

	}


	/**

	 * Specifies the access control rules.

	 * This method is used by the 'accessControl' filter.

	 * @return array access control rules

	 */

	public function accessRules()

	{

		return array(

			array('allow',

				'actions'=>array('error','login','captcha','gii'),

				'users'=>array('*'),

			),

			array('allow',

				'actions'=>array('index','logout','about','contact'),

				'users'=>array('@'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}


	/**

	 * 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);

				

				/*$model1= new LoginForm;

				

				$model1->username=$username;

				$model1->password=$password;

				

				if($model1->login())

					$this->redirect(array('site/index'));*/

		}

		// 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);

	}

}

Ini model TBLUSR.php (model yang terhubung dengan tabel user)


<?php


/**

 * This is the model class for table "TBL_USR".

 *

 * The followings are the available columns in table 'TBL_USR':

 * @property integer $USR_ID

 * @property integer $EMP_ID

 * @property string $USR_NAME

 * @property string $PASSWORD

 * @property string $CONFR_PASSWORD

 * @property integer $AS_ID

 * @property integer $CREATOR_ID

 *

 * The followings are the available model relations:

 * @property TBLEMP[] $tBLEMPs

 */

class TBLUSR extends CActiveRecord

{

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'TBL_USR';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('PASSWORD', 'required'),

			array('EMP_ID, AS_ID, CREATOR_ID', 'numerical', 'integerOnly'=>true),

			array('USR_NAME, CONFR_PASSWORD', 'length', 'max'=>20),

			array('PASSWORD', 'length', 'max'=>50),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('USR_ID, EMP_ID, USR_NAME, PASSWORD, CONFR_PASSWORD, AS_ID, CREATOR_ID', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'tBLEMPs' => array(self::HAS_MANY, 'TBLEMP', 'CREATOR_ID'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'USR_ID' => 'Usr',

			'EMP_ID' => 'Emp',

			'USR_NAME' => 'Usr Name',

			'PASSWORD' => 'Password',

			'CONFR_PASSWORD' => 'Confr Password',

			'AS_ID' => 'As',

			'CREATOR_ID' => 'Creator',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 *

	 * Typical usecase:

	 * - Initialize the model fields with values from filter form.

	 * - Execute this method to get CActiveDataProvider instance which will filter

	 * models according to data in model fields.

	 * - Pass data provider to CGridView, CListView or any similar widget.

	 *

	 * @return CActiveDataProvider the data provider that can return the models

	 * based on the search/filter conditions.

	 */

	public function search()

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('USR_ID',$this->USR_ID);

		$criteria->compare('EMP_ID',$this->EMP_ID);

		$criteria->compare('USR_NAME',$this->USR_NAME,true);

		$criteria->compare('PASSWORD',$this->PASSWORD,true);

		$criteria->compare('CONFR_PASSWORD',$this->CONFR_PASSWORD,true);

		$criteria->compare('AS_ID',$this->AS_ID);

		$criteria->compare('CREATOR_ID',$this->CREATOR_ID);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	public function validatePassword ($password)

	{

		return ($this->PASSWORD);

	}

	

	

	

	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return TBLUSR the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}



salah di identitynya gan, mestinya return valunya dibalik, yg error gak bisa masuk


       

        private $_id;

        public $username;

        public $password;

        

        public function authenticate()

        {

                $username = ($this->username);

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

                $pwd = TBLUSR::model()->findByAttributes(array('PASSWORD'=>$this->password));

                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->USR_ID;

                        $this->username = $user->USR_NAME;

                        $this->password = $user->PASSWORD;

                        

                        $this->errorCode=self::ERROR_NONE;

                }

                return ! $this->errorCode; //baris ini nih

        }  



kmren udh saya cb, tp kok malah g bisa masuk dua-duanya ya?

ya, UserIdentity.authenticate() mestinya returnnya false (jika error) atau true (jika berhasil), sedangkan kode error self::ERROR_NONE itu isinya 0, selain 0 dianggap pesan error (1: account gak ada, 2 password salah, 100: unknown identity, cek dokumentasinya).

Sehingga waktu mau direturn harus dinegasikan, karena 0 artinya validasi OK - no error, selain itu berarti ada error.

Kalo abis diganti malah gak bisa masuk, sepertinya salah di logika, coba kode ente:




public function authenticate()

        {

                $username = ($this->username);

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

                $pwd = TBLUSR::model()->findByAttributes(array('PASSWORD'=>$this->password));

                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->USR_ID;

                        $this->username = $user->USR_NAME;

                        $this->password = $user->PASSWORD;

                        

                        $this->errorCode=self::ERROR_NONE;

                }

                return ! $this->errorCode; //baris ini nih

        } 



kalo usernya nggak ada, error 1, tapi kalo usernya ada validate password? sekarang cek kodenya validate password:




        public function validatePassword ($password)

        {

                return ($this->PASSWORD);

        }



method ini akan mengembalikan password dari user, lalu baris pengecekan if (!$user->validatePassword($this->password)) otomatis nilainya akan selalu true selama user punya password, saya kira kode yg lebih tepat untuk validate password adalah perbandingan antara password user dengan password yg dientri, misal:




        public function validatePassword ($password)

        {

                return ($this->PASSWORD == $password);

        }



atau kalo password anda dihash:




        public function validatePassword ($plainPassword)

        {

                //$result = ($this->PASSWORD == sha1($plainPassword));

                //$result = ($this->PASSWORD == md5($this->SALT . $plainPassword));

                $result = ($this->PASSWORD == md5($plainPassword));


                return $result;

        }



contoh otentikasi menggunakan db bisa dilihat di artikel ini, atau ini.

wah makasih om, ternyata script validate passwordnya :)

asalnya




        public function validatePassword ($password)

        {

                return ($this->PASSWORD);

        }



yang betul punya Om daudtm :




        public function validatePassword ($password)

        {

                return ($this->PASSWORD == $password);

        }



sekarang sudah SOLVED… :)