ویرایش پسورد(کلمه عبور) - Change Password

[size="3"][font="Tahoma"][right]سلام

من یه جدول برای کاربرا دارم که برای ورود نام کاربری کلمه عبور دارن

با جی آی آی مدل و کنترل و ویوشو ساختم

یه تابع داخل مدل ساختم و بعد اینجوری ازش استفاده کردم

[left]




protected function afterValidate()

{

   parent::afterValidate();

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

}

public function encrypt($value)

{

  return md5($value);

}



[/left]

وقتی دارم کاربر جدید تعریف میکنم خب مشکلی نیست هنگام ذخیره این تابع فراخوانی میشه و پسورد کد میشه

مشکلی که الان دارم اینه که وقتی بخوام اون کاربر رو ویرایش کنم

اگه کاربر مقدار جدید واسه پسورد وارد کنه

خب مجددا کد میشه اما اگه نخواد پسوردو ویرایش کنه،هرچی داخل تکست باکس پسورد باشه کد میشه

چه خالی باشه چه اینکه مرورگر اون فیلد رو پر کنه

(مثلا در فایرفاکس اگه نام کاربری و کلمه عبور رو ذخیره کنیم توی این صفحه اگه نام کاربری رو انتخاب کنیم داخل باکس پسورد مقدار میاره که اینم یه مشکل دیگست)

من کدهاییکه دارمو میذارم

اگه کسی راهکاری داری ممنون میشم اینجا بگه تا استفاده کنیم

[left]

Controller:




class PersonController extends Controller

{

        /**

         * @var string the default layout for the views. Defaults to '//layouts/column2', meaning

         * using two-column layout. See 'protected/views/layouts/column2.php'.

         */

        public $layout='//layouts/column2';


        /**

         * @return array action filters

         */

        public function filters()

        {

                return array(

                        'accessControl', // perform access control for CRUD operations

                        'postOnly + delete', // we only allow deletion via POST request

                );

        }


        /**

         * 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',  // allow all users to perform 'index' and 'view' actions

                                'actions'=>array('index','view'),

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

                        ),

                        array('allow', // allow authenticated user to perform 'create' and 'update' actions

                                'actions'=>array('create','update'),

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

                        ),

                        array('allow', // allow admin user to perform 'admin' and 'delete' actions

                                'actions'=>array('admin'),//,'delete'),

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

                        ),

                        array('deny',  // deny all users

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

                        ),

                );

        }


        /**

         * Displays a particular model.

         * @param integer $id the ID of the model to be displayed

         */

        public function actionView($id)

        {

                $this->render('view',array(

                        'model'=>$this->loadModel($id),

                ));

        }


        /**

         * Creates a new model.

         * If creation is successful, the browser will be redirected to the 'view' page.

         */

        public function actionCreate()

        {

                $model=new PersonModel;


                // Uncomment the following line if AJAX validation is needed

                // $this->performAjaxValidation($model);


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

                {

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

                        if($model->save())

                                $this->redirect(array('view','id'=>$model->person_id));

                }

                $model->person_password=null;

                $model->password_repeat=null;

                $this->render('create',array(

                        'model'=>$model,

                ));

        }


        /**

         * Updates a particular model.

         * If update is successful, the browser will be redirected to the 'view' page.

         * @param integer $id the ID of the model to be updated

         */

        public function actionUpdate($id)

        {

                $model=$this->loadModel($id);

                //$model->scenario='update';

                //$check_passs = $this->loadModel($id);

                // Uncomment the following line if AJAX validation is needed

                // $this->performAjaxValidation($model);


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

                {

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

                        /*if($model->person_password === $check_passs->person_password)

                        {

                                // Not Change

                                $model->person_password = $check_passs->person_password;

                        }

                        else

                        {

                                // Changed

                                $model->person_password = PersonModel::model()->encrypt($check_passs->person_password);

                        }//exit;*/

                        if($model->save())

                                $this->redirect(array('view','id'=>$model->person_id));

                }

                $model->person_password="";

                //$model->password_repeat=null;

                $this->render('update',array(

                        'model'=>$model,

                ));

        }


        /**

         * Deletes a particular model.

         * If deletion is successful, the browser will be redirected to the 'admin' page.

         * @param integer $id the ID of the model to be deleted

         */

        public function actionDelete($id)

        {

                $this->loadModel($id)->delete();


                // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

                if(!isset($_GET['ajax']))

                        $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

        }


        /**

         * Lists all models.

         */

        public function actionIndex()

        {

                $dataProvider=new CActiveDataProvider('PersonModel');

                $this->render('index',array(

                        'dataProvider'=>$dataProvider,

                ));

        }


        /**

         * Manages all models.

         */

        public function actionAdmin()

        {

                $model=new PersonModel('search');

                $model->unsetAttributes();  // clear any default values

                if(isset($_GET['PersonModel']))

                        $model->attributes=$_GET['PersonModel'];


                $this->render('admin',array(

                        'model'=>$model,

                ));

        }


        /**

         * Returns the data model based on the primary key given in the GET variable.

         * If the data model is not found, an HTTP exception will be raised.

         * @param integer the ID of the model to be loaded

         */

        public function loadModel($id)

        {

                $model=PersonModel::model()->findByPk($id);

                if($model===null)

                        throw new CHttpException(404,'The requested page does not exist.');

                return $model;

        }


        /**

         * Performs the AJAX validation.

         * @param CModel the model to be validated

         */

   protected function performAjaxValidation($model)

   {

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

      {

         echo CActiveForm::validate($model);

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

       }

   }       

        

}




Model:




/**

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

 *

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

 * @property integer $person_id

 * @property string $person_name

 * @property string $person_family

 * @property string $person_username

 * @property string $person_password

 * @property string $person_datelastlogin

 */

class PersonModel extends CActiveRecord

{

        public $password_repeat;

        

        /**

         * Returns the static model of the specified AR class.

         * @param string $className active record class name.

         * @return PersonModel the static model class

         */

        public static function model($className=__CLASS__)

        {

                return parent::model($className);

        }


        /**

         * @return string the associated database table name

         */

        public function tableName()

        {

                return 'person';

        }


        /**

         * @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('person_name, person_family, person_username, person_password, password_repeat', 'required'),

                        array('person_name, person_family, person_username', 'length', 'max'=>70),

                        array('person_password', 'length', 'max'=>128),

                        array('person_username', 'unique'),

                        array('person_datelastlogin', 'length', 'max'=>12),

                        array('person_password', 'compare', 'compareAttribute'=>'password_repeat'),

                        array('password_repeat', 'safe'),

                

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

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

                        array('person_id, person_name, person_family, person_username, person_password, person_datelastlogin', 'safe'),//, 'on'=>'search'),

                );

        }


                protected function afterValidate()

                {

                        parent::afterValidate();

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

                }

                public function encrypt($value)

                {

                        return md5($value);

                }


        /**

         * @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(

                );

        }


        /**

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

         */

        public function attributeLabels()

        {

                return array(

                        'person_id' => 'Person',

                        'person_name' => 'Person Name',

                        'person_family' => 'Person Family',

                        'person_username' => 'Person Username',

                        'person_password' => 'Person Password',

                        'person_datelastlogin' => 'Person Datelastlogin',

                );

        }


        /**

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

         * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

         */

         

         

        public function search()

        {

                // Warning: Please modify the following code to remove attributes that

                // should not be searched.


                $criteria=new CDbCriteria;


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

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

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

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

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

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


                return new CActiveDataProvider($this, array(

                        'criteria'=>$criteria,

                ));

        }

}




View: _form.php





<?php

/* @var $this NewsController */

/* @var $model NewsModel */

/* @var $form CActiveForm */

?>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

        'id'=>'news-model-form',

        'enableAjaxValidation'=>false,

)); ?>


        <p class="note">پر کردن فیلدهای <span class="required">*</span> دار الزامی است.


        <?php echo $form->errorSummary($model); ?>


        <div class="row">

                <?php echo $form->labelEx($model,'title'); ?>

                <?php echo $form->textField($model,'title',array('size'=>60,'maxlength'=>3000)); ?>

                <?php echo $form->error($model,'title'); ?>

        </div>


<script src="<?php echo Yii::app()->baseUrl.'/ckeditor_4/ckeditor.js'; ?>"></script>

        <div class="row">

                <?php echo $form->labelEx($model,'text'); ?>

                <?php echo $form->textArea($model,'text',array('id'=>'editor1')); ?>

                <?php echo $form->error($model,'text'); ?>

        </div>

<script type="text/javascript">

    CKEDITOR.replace( 'editor1',{

                                        height : "200px",

                                        width : "500px",

                                        toolbar :

                                        [

                                          ['Source','-','Save','Preview'],

                                          ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],

                                          ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],

                                          ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],

                                          ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],

                                          ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],

                                          ['Link','Unlink','Anchor'],

                                          ['Image','Table','HorizontalRule','SpecialChar']

                                        ],

                                        //uiColor : '#f2f2f2',

                                        //skin : 'basic',

                                        language : 'fa',

                                        filebrowserBrowseUrl: '<?php echo Yii::app()->baseUrl; ?>/kcfinder/browse.php?type=files',

                                         filebrowserImageBrowseUrl: '<?php echo Yii::app()->baseUrl; ?>/kcfinder/browse.php?type=images',

                                         filebrowserFlashBrowseUrl: '<?php echo Yii::app()->baseUrl; ?>/kcfinder/browse.php?type=flash',

                                         filebrowserUploadUrl: '<?php echo Yii::app()->baseUrl; ?>/kcfinder/upload.php?type=files',

                                         filebrowserImageUploadUrl: '<?php echo Yii::app()->baseUrl; ?>/kcfinder/upload.php?type=images',

                                         filebrowserFlashUploadUrl: '<?php echo Yii::app()->baseUrl; ?>/kcfinder/upload.php?type=flash'

                    

        });

</script>


        <div class="row">

                <?php //echo $form->labelEx($model,'date_insert'); ?>

                <?php //echo $form->textField($model,'date_insert',array('size'=>12,'maxlength'=>12)); ?>

                <?php //echo $form->error($model,'date_insert'); ?>

        </div>


        <div class="row">

                <?php //echo $form->labelEx($model,'date_update'); ?>

                <?php //echo $form->textField($model,'date_update',array('size'=>12,'maxlength'=>12)); ?>

                <?php //echo $form->error($model,'date_update'); ?>

        </div>


        <div class="row">

                <?php //echo $form->labelEx($model,'person_id'); ?>

                <?php //echo $form->textField($model,'person_id'); ?>

                <?php //echo $form->error($model,'person_id'); ?>

        </div>


        <div class="row">

                <?php echo $form->labelEx($model,'keywords'); ?>

                <?php echo $form->textField($model,'keywords',array('size'=>60,'maxlength'=>1024)); ?>

                <?php echo $form->error($model,'keywords'); ?>

        </div>


        <div class="row">

                <?php //echo $form->labelEx($model,'emtiaz'); ?>

                <?php //echo $form->textField($model,'emtiaz'); ?>

                <?php //echo $form->error($model,'emtiaz'); ?>

        </div>


        <div class="row">

                <?php //echo $form->labelEx($model,'bazdid'); ?>

                <?php //echo $form->textField($model,'bazdid'); ?>

                <?php //echo $form->error($model,'bazdid'); ?>

        </div>


  <div class="row">

                <?php echo $form->labelEx($model,'active'); ?>

                <?php echo $form->dropDownList($model,'active', $model->getActiveOption()); ?>

                <?php echo $form->error($model,'active'); ?>

        </div>


        <div class="row">

                <?php echo $form->labelEx($model,'group_id'); ?>

        <?php $list = CHtml::listData($model->getGroupOption(), 'id', 'name');?>

                <?php echo $form->dropDownList($model,'group_id', $list); ?>

                <?php echo $form->error($model,'group_id'); ?>

        </div>


        <div class="row buttons">

                <?php echo CHtml::submitButton($model->isNewRecord ? Yii::t('txt', 'Create') : Yii::t('txt', 'Save')); ?>

        </div>


<?php $this->endWidget(); ?>


</div><!-- form -->



[/left]

[/right][/font][/size]

[rtl]

[size="2"][font="Tahoma"]منم همچين مشکلي رو با فايرفاکس داشتم. حتي اگر مقدار فيلد پسورد رو نال مي کردم بازم مرورگر توي فيلد پسورد مي گذاشت. (فکر مي کنم با توجه به فرم لاگين)

راهي که من پيشنهاد ميدم اينه که: فيلد پسوردتون person_password هست ولي توي مدل يک old_password تعريف کنيد و از اون توي view استفاده کنين. newpass1 و newpass2 هم تعريف کنيد که مقدار جديد عبور با تکرارش هست.

دو تا مزيتي که داره اينه که:

با اين روش فيلدها خودکار پر نميشن چون نه توي ديتابيس اين ستون ها رو داريم نه توي فرم لاگين يا عضويت که بخواد مرورگر به طور خودکار مقدار بده.

کاربر اگه بخواد پسورد عوض کنه نيازه که پسورد قديم رو وارد کنه که امنيت بيشتري رو باعث ميشه.

حالا لازمه که اگه old_password مقدار داشت مقدارش رو با مقدار توي پايگاه داده چک کنين اگه برابر بود اگه newpass1 و newpass2 مقدارشون برابر بود توي پايگاه داده ذخيره کنيد[/font][/size] [/rtl]

[right][font="Tahoma"]

ممنونم از راهنماییتون

یه مشکل دیگه هم وجود داره ،اینه که اگه کاربر هنگام ویرایش نخواد پسورد رو ویرایش کنه

اونوقت هنگام عمل

$model->save()

دوباره مقدار پسورد که خالی رها شده کدمیشه

چطور این مشکلو باید حل کرد؟

[/font][/right]

[right][rtl]

سلام

دوستان ببخشید که فرصت توضیح کامل ندارم.

فقط دیدم این تاپیک خیلی وقته به نتیجه نرسیده ، گفتم تجربیاتم شاید به دردتون بخوره.

کلا اولین راه معمول برای این کار اینه که شما در فرم ثبت نام چک میکنید که اگر رکورد جدید نبود و رندر فرم برای آپدیت انجام شده ، فیلد پسورد رو اصلا چاپ نمیکنید که مشکلات autocomplete مررورگر یا hashing مجدد پیش بیاد.

کاربر فقط میتونه اطلاعات عمومی غیر از پسورد رو ویرایش کنه و برای پسورد یک فرم دیگر در نظر میگیرید که پسورد قبلی و جدید رو میگیرید و در کنترلر چک میکنید اگر پسورد قبلی کاربر با پسورد دیتابیس همخوانی داشت ، پسورد جدید رو ذخیره میکنید.

در کل باید فرم درخواست تغییر پسورد از فرم پروفایل جدا باشه.

البته بهتره برای راحتی کار و تغییرات احتمالی در آینده مثل ارسال پسورد فراموش شده به ایمیل کاربر، یک اکشن جدید برای فرم تغییر پسورد بنویسید که بعدا راحت بشه براش سناریو نوشت.

موفق باشید

[/rtl]

[left]_form.php




	<div class="row">

		<?php echo $form->labelEx($model,'UserName'); ?>

		<?php echo $form->textField($model,'UserName',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'UserName'); ?>

	</div>

<?php if($model->isNewRecord){?>

	<div class="row">

		<?php echo $form->labelEx($model,'Password'); ?>

		<?php echo $form->passwordField($model,'Password',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'Password'); ?>

	</div>

<?php } ?>

	<div class="row">

		<?php echo $form->labelEx($model,'FirstName'); ?>

		<?php echo $form->textField($model,'FirstName',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'FirstName'); ?>

	</div>



فرم جدید برای تغییر پسورد





<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'changePass-form',

	'enableAjaxValidation'=>false,

    	'enableClientValidation'=>true,

)); ?>




	<?php echo $form->errorSummary($model); ?>


	<div class="row">

		<?php echo $form->labelEx($model,'Current'); ?>

		<?php echo $form->textField($model,'Current',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'Current'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'Password'); ?>

		<?php echo $form->passwordField($model,'Password',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'Password'); ?>

	</div>

    	

    	<div class="row">

		<?php echo $form->labelEx($model,'ReType'); ?>

		<?php echo $form->passwordField($model,'ReType',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'ReType'); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::submitButton('save'); ?>

	</div>


<?php $this->endWidget(); ?>







[/left]

[/right]

[right][font="Tahoma"]

دوستان از توجه و راهنماییتون خیلی ممنونم

باساخت فرم جدا مشکل ویرایش پسورد حل شد

اما

این مشکل در قسمت ویرایش فیلدهای دیگه،همچنان وجود داره

ببینید در فرم ویرایش اطلاعات پروفایل،همه فیلدها بغیر از پسورد وجود داره،که پسورد رو در یک فرم دیگه باپیشنهادات خوب شما ویرایش میکنم

اما در هنگام ویرایش اطلاعات پروفایل،با توجه به اینکه فیلد پسوردی وجود نداره اما بخاطر تابع زیر،فیلد پسورد مجددا کد میشه

[left]




protected function afterValidate()

{

   parent::afterValidate();

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

}

public function encrypt($value)

{

     return md5($value);

}



[/left]

[/font][/right]

[right][rtl]

دوست عزیز اولا که بهتره این کار رو در متد beforeSave انجام بدید.

و در این متد هم چک کنید که hashing فقط در زمان ایجاد رکورد جدید یا سناریو تغییر پسورد انجام بشه.

در مورد سناریو مختصر بگم که مثلا من اکشن actionCpass رو برای تغییر پسورد ایجاد کردم .

مقایسه پسوردهای جدید و قدیم و در نهایت ذخیره در این اکشن انجام میشه.

سناریو پیش فرض اکشن create عبارتinsert هست و برای update هم از همان update استفاده میشه و من برای اکشن Cpass در این متد بعد از ساخت مدل ، یک سناریو به اون اختصاص دادم.

[left][right][/rtl]

[/right]




public function actionCpass(){

        	

        	$model=new users;

        	$model->scenario = 'Cpass';

.....

}



[/left]

[rtl]

در قسمت rules در مدل هم میتونید بر اساس این سناریو rule تعریف کنید.

[/rtl]

[left]




public function rules()

	{

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

		// will receive user inputs.

		return array(

array('Current, ReType', 'required', 'on'=>'Cpass'),

);

.....

}



[/left]

[left]




    	public function beforeSave() {

		if ($this->isNewRecord || $this->scenario == 'Cpass'){

		$this->Password = UserIdentity::encrypt($this->Password);

		}

        	

		return parent::beforeSave();

	}



[/left][/right]

[font="Tahoma"][right]خیلی ممنون از راهنمایی مفیدتون

مشکلاتم حل شد

:)

[/right][/font]

[font="Tahoma"][rtl]از ویژگی autoComplete خود html هم میشه استفاده کرد[/rtl][/font]


'autoComplete'='off'