Crypt для пароля

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
maximatorrus
Сообщения: 124
Зарегистрирован: 2014.01.21, 09:30

Crypt для пароля

Сообщение maximatorrus »

Здравствуйте, форумчане!
Проблема в следующем. Для хеширования пароля у меня используется crypt. При добавлении нового пользователя введенный пароль преобразуется. Это норм. Но если зайти в экшен update, то мы увидим в поле Password - хешированный код, и при изменении его и последующем сохранении-в базу он заносится как обычные символы.

Как сделать, чтобы в экшене update в поле Password выводилось перекодированный пароль их crypt в нормальный, и при обновлении его-в базу заносился криптованный.

Привожу код модели User.php

Код: Выделить всё

<?php

/**
 * This is the model class for table "user".
 *
 * The followings are the available columns in table 'user':
 * @property integer $id
 * @property string $login
 * @property string $username
 * @property string $password
 * @property string $email
 * @property string $role
 * @property integer $lpu_id
 */
class User extends CActiveRecord
{
    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return User 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 'user';
    }

    /**
     * @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('login, username, password, email, role, lpu_id', 'required'),
            array('lpu_id', 'numerical', 'integerOnly'=>true),
            array('login, username, password, email, role', 'length', 'max'=>128),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, login, username, password, email, role, lpu_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(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'login' => 'Login',
            'username' => 'Username',
            'password' => 'Password',
            'email' => 'Email',
            'role' => 'Role',
            'lpu_id' => 'Lpu_id',
        );
    }

    /**
     * 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('id',$this->id);
        $criteria->compare('login',$this->login,true);
        $criteria->compare('username',$this->username,true);
        $criteria->compare('password',$this->password,true);
        $criteria->compare('email',$this->email,true);
        $criteria->compare('role',$this->role,true);
        $criteria->compare('lpu_id',$this->lpu_id);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }
    protected function beforeSave()
    {
        if(parent::beforeSave())
        {
            if($this->isNewRecord)
            {
                // Хешировать пароль
                $hash_pass = crypt($this->password);
                $this->password = $hash_pass;
            }
            return true;
        }
        return false;
    }
}
Именно функция beforeSave отвечает за преобразование пароля при СОЗДАНИИ.

Код user/update.php

Код: Выделить всё

<?php
/* @var $this UserController */
/* @var $model User */

$this->breadcrumbs=array(
    'Users'=>array('index'),
    $model->id=>array('view','id'=>$model->id),
    'Update',
);
if(Yii::app()->user->checkAccess('admin')):
    echo $this->renderPartial('_form', array('model'=>$model));

$this->menu=array(
    array('label'=>'List User', 'url'=>array('index')),
    array('label'=>'Create User', 'url'=>array('create')),
    array('label'=>'View User', 'url'=>array('view', 'id'=>$model->id)),
    array('label'=>'Manage User', 'url'=>array('admin')),
);

endif;
?>

<h1>Update User <?php echo $model->id; ?></h1>
И собственно код user/_form.php откуда задается вывод полей

Код: Выделить всё

<?php
/* @var $this UserController */
/* @var $model User */
/* @var $form CActiveForm */
?>

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'user-form',
    'enableAjaxValidation'=>false,
)); ?>

    <p class="note">Fields with <span class="required">*</span> are required.</p>

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

    <div class="row">
        <?php echo $form->labelEx($model,'login'); ?>
        <?php echo $form->textField($model,'login',array('size'=>60,'maxlength'=>128)); ?>
        <?php echo $form->error($model,'login'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'username'); ?>
        <?php echo $form->textField($model,'username',array('size'=>60,'maxlength'=>128)); ?>
        <?php echo $form->error($model,'username'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'password'); ?>
        <?php echo $form->passwordField($model,'password',array('size'=>60,'maxlength'=>128)); ?>
        <?php echo $form->error($model,'password'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'email'); ?>
        <?php echo $form->textField($model,'email',array('size'=>60,'maxlength'=>128)); ?>
        <?php echo $form->error($model,'email'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'role'); ?>
        <?php echo $form->textField($model,'role',array('size'=>60,'maxlength'=>128)); ?>
        <?php echo $form->error($model,'role'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'lpu_id'); ?>
        <?php echo $form->textField($model,'lpu_id'); ?>
        <?php echo $form->error($model,'lpu_id'); ?>
    </div>

    <div class="row buttons">
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
    </div>

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

</div><!-- form -->
kawabanga
Сообщения: 806
Зарегистрирован: 2013.10.12, 23:35
Откуда: Новосибирск

Re: Crypt для пароля

Сообщение kawabanga »

При сохранении вам нужно вводить пароль? т.е. при любом из вариантов, вы передаете незашифрованный пароль при сохранении? Вероятно вот так вам нужно:

Код: Выделить всё

 protected function beforeSave()
    {
        if(parent::beforeSave())
        {
            
                // Хешировать пароль
                $hash_pass = $hash_pass;

            return true;
        }
        return false;
    } 
maximatorrus
Сообщения: 124
Зарегистрирован: 2014.01.21, 09:30

Re: Crypt для пароля

Сообщение maximatorrus »

kawabanga писал(а):При сохранении вам нужно вводить пароль? т.е. при любом из вариантов, вы передаете незашифрованный пароль при сохранении? Вероятно вот так вам нужно:

Код: Выделить всё

 protected function beforeSave()
    {
        if(parent::beforeSave())
        {
            
                // Хешировать пароль
                $hash_pass = $hash_pass;

            return true;
        }
        return false;
    }

Ура! Спасибо! Точно, как же я не догадался! То есть при любых условиях кодируем.
А как при просмотре пользователя user/view/... в поле password отображался не кодированный пароль? чтоб пользователю можно было глянуть и вспомнить на всякий случай.
kawabanga
Сообщения: 806
Зарегистрирован: 2013.10.12, 23:35
Откуда: Новосибирск

Re: Crypt для пароля

Сообщение kawabanga »

а зачем вам тогда вообще все хэширования нужны? Хэширование нужно, что бы тот, у кого есть несанкционированный доступ к базе, не мог получить реальное значение пароля.
kawabanga
Сообщения: 806
Зарегистрирован: 2013.10.12, 23:35
Откуда: Новосибирск

Re: Crypt для пароля

Сообщение kawabanga »

как вариант - при регистрации, высылайте пароль на мыло оригинал.
Если пароль забыт - делайте новый.
kawabanga
Сообщения: 806
Зарегистрирован: 2013.10.12, 23:35
Откуда: Новосибирск

Re: Crypt для пароля

Сообщение kawabanga »

Сверху опечатку допустил, правильно вот так , не те переменные удалил(

Код: Выделить всё

 
                $this->password = rypt($this->password); 
maximatorrus
Сообщения: 124
Зарегистрирован: 2014.01.21, 09:30

Re: Crypt для пароля

Сообщение maximatorrus »

kawabanga писал(а):Сверху опечатку допустил, правильно вот так , не те переменные удалил(

Код: Выделить всё

 
                $this->password = rypt($this->password);
Да, я уже догадался, сделал.
Спасибо! Вашу мысль я понял, очень уместная! Оставлю как есть!
Странник
Сообщения: 293
Зарегистрирован: 2013.04.08, 10:35
Откуда: Нижний Новгород

Re: Crypt для пароля

Сообщение Странник »

А я не понял. :(
Можно для меня повторить?
У меня при создании пользователя пароль кешируется.
Но при апдейте он не кешируется.
То есть если я меняю пароль, то необходимо проверять совпадают ли кеш в БД и передаваемый и если не совпадают, то заново кешировать и сохранять???
А как это выглядит в реале?

Сейчас у меня так, но пароли при апдейте портятся.

Код: Выделить всё

protected function beforeSave()
{
if(parent::beforeSave())
   {
      if($this->isNewRecord)   
      {
         $this->password = crypt($this->password) ; 
         return true;
      }
      else return true;
   }
else return false;
} 
maximatorrus
Сообщения: 124
Зарегистрирован: 2014.01.21, 09:30

Re: Crypt для пароля

Сообщение maximatorrus »

Странник писал(а):А я не понял. :(
Можно для меня повторить?
У меня при создании пользователя пароль кешируется.
Но при апдейте он не кешируется.
То есть если я меняю пароль, то необходимо проверять совпадают ли кеш в БД и передаваемый и если не совпадают, то заново кешировать и сохранять???
А как это выглядит в реале?

Сейчас у меня так, но пароли при апдейте портятся.

Код: Выделить всё

protected function beforeSave()
{
if(parent::beforeSave())
   {
      if($this->isNewRecord)   
      {
         $this->password = crypt($this->password) ; 
         return true;
      }
      else return true;
   }
else return false;
}

Просто убираешь проверку на новую запись, и получается что пароль будет кешироваться и при создании, и при обновлении записи.
То есть вот так.

Код: Выделить всё

protected function beforeSave()
    {
        if(parent::beforeSave())
        {
                // Хешировать пароль
                $hash_pass = crypt($this->password);
                $this->password = $hash_pass;
            return true;
        }
        return false;
    } 
HQ0
Сообщения: 182
Зарегистрирован: 2012.10.17, 17:21

Re: Crypt для пароля

Сообщение HQ0 »

Странник, хеш и кеш немного разные вещи, не ошибайся :)
А вообще, можно создать виртуальное поле в модельку, в форме работать с ним и в beforeSave проверять не пустое ли это новое поле
Странник
Сообщения: 293
Зарегистрирован: 2013.04.08, 10:35
Откуда: Нижний Новгород

Re: Crypt для пароля

Сообщение Странник »

В этом случае если пароль не менялся он захешируется второй раз. И после этого не будет работать.
А вот как сделать, чтобы он записывался только в случае обновления?
maximatorrus писал(а): Просто убираешь проверку на новую запись, и получается что пароль будет кешироваться и при создании, и при обновлении записи.
То есть вот так.

Код: Выделить всё

protected function beforeSave()
    {
        if(parent::beforeSave())
        {
                // Хешировать пароль
                $hash_pass = crypt($this->password);
                $this->password = $hash_pass;
            return true;
        }
        return false;
    } 
Опечатался. :)
HQ0 писал(а):Странник, хеш и кеш немного разные вещи, не ошибайся :)
Странник
Сообщения: 293
Зарегистрирован: 2013.04.08, 10:35
Откуда: Нижний Новгород

Re: Crypt для пароля

Сообщение Странник »

Решено.:)
Ответить