аутентификация, хэш, соли

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

аутентификация, хэш, соли

Сообщение des1roer »

вот нашел хороший туториал
http://loco.ru/materials/177-yii-course ... vtorizacii
настроил соли, хэш
Изображение
пытаюсь в useridentity
поменять

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

$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;
на

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

$user=Myuser::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;
но залогиниться не могу. во втором коде не вижу соли, может в этом проблема? или yii автоматом их подхватывает?
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение SiZE »

Мануал хороший, но устаревший. Плюс соль такой длины вовсе незачем хранить, 3-5 символов за глаза. В Й есть нативный и более удобный способ шифрования паролей через CPasswordHelper. И даже отдельное поле для хранения соли не понадобится.
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение SiZE »

des1roer писал(а):как выкрутился http://des1roer.blogspot.ru/2015/02/yii.html
Ишо раз. Те кто случайно зайдут в эту тему. Не мудите, делайте через CPasswordHelper. Аминь.
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

млин пытаюсь сделать бан.
class UserIdentity extends CUserIdentity {

private $_id;

public function authenticate() {
$user = User::model()->find('LOWER(u_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 {
if ($user->ban != 1) {
$this->_id = $user->u_id;
$this->username = $user->u_username;
$this->errorCode = self::ERROR_NONE;
} else {
$this->layout = '';
$this->render('application.system.404');
}
}
return !$this->errorCode;
}

public function getId() {
return $this->_id;
}

}
бан срабатывает не корректно. он просто ломает пароль и нужно его по новой вводить в базе. как решить? в модели юзер есть булевое поле бан
Onotole
Сообщения: 1808
Зарегистрирован: 2012.12.24, 12:49

Re: аутентификация, хэш, соли

Сообщение Onotole »

В модели в afterFind пароль както обрабатываете?
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

да в общем то все утыкается в то что после каждого аплейта пароль и соль пересчитываются заново. не могу понять как подебить

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

<?php

/**
 * This is the model class for table "vgok_user".
 *
 * The followings are the available columns in table 'vgok_user':
 * @property integer $u_id
 * @property string $u_username
 * @property string $u_password
 * @property string $u_salt
 * @property integer $role_r_id
 * @property string $u_comment
 * @property string $u_created
 * @property string $u_ban_date
 * @property integer $u_dep
 * @property integer $u_sector
 * @property integer $ban
 *
 * The followings are the available model relations:
 * @property Engine[] $engines
 * @property Role $roleR
 * @property Department $uDep
 * @property Department $uSector
 */
class User extends CActiveRecord
{

    public $new_password;

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'vgok_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('u_username, u_password, u_created', 'required'),
            array('role_r_id, u_dep, u_sector, ban', 'numerical', 'integerOnly' => true),
            array('u_username', 'match', 'pattern' => '#^[a-zA-Z0-9_\.-]+$#', 'message' => 'Логин содержит запрещённые символы'),
            array('u_username', 'unique', 'caseSensitive' => false),
            array('u_username', 'length', 'max' => 45),
            array('u_password, u_salt', 'length', 'max' => 255),
            array('u_comment, u_ban_date', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('u_id, u_username, u_password, u_salt, role_r_id, u_comment, u_created, u_ban_date, u_dep, u_sector, ban', '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(
            'engines' => array(self::HAS_MANY, 'Engine', 'user_u_id'),
            'roleR' => array(self::BELONGS_TO, 'Role', 'role_r_id'),
            'uDep' => array(self::BELONGS_TO, 'Department', 'u_dep'),
            'uSector' => array(self::BELONGS_TO, 'Department', 'u_sector'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'u_id' => 'ид',
            'u_username' => 'логин',
            'u_password' => 'пароль',
            'u_salt' => 'соль',
            'role_r_id' => 'роль',
            'u_comment' => 'комментарий',
            'u_created' => 'дата создания',
            'u_ban_date' => 'дата блокировки',
            'u_dep' => 'отдел',
            'u_sector' => 'участок',
            'ban' => 'бан',
        );
    }

    protected function afterFind()
    {
        $result = Role::model()->findByPk($this->role_r_id);
        if ($result)
            $this->role_r_id = $result->r_name;
        $new_password = $this->u_password;
    }

    //регистрация
//регистрация     
    protected function beforeSave()
    {
        //echo '<pre>';
        //var_dump($_POST['User']['u_password']);
        if ($this->ban == 1)
            $this->u_ban_date = date('Y-m-d H:i:s');
        else
        {
            $this->u_ban_date = '';
        }
        if ($this->isNewRecord || $new_password != $_POST['User']['u_password'])
        {
            $this->u_salt = self::generateSalt();
            $this->u_password = $this->hashPassword($this->u_password, $this->u_salt);
        }
        return parent::beforeSave();
    }

    // После валидации присваиваем пароль и соль.
    /*  public function afterValidate()
      {
      $this->u_password = self::hashPassword($this->u_password, $this->u_salt);
      if($this->isNewRecord) {
      $salt = self::generateSalt();
      $this->u_password = self::hashPassword($this->u_password, $salt);
      $this->u_salt = $salt;
      //$this->role = 'user';
      }
      return true;
      }
     */

    /**
     * Checks if the given password is correct.
     * @param string the password to be validated
     * @return boolean whether the password is valid
     */
    public function validatePassword($password)
    {
        
            return $this->hashPassword($password, $this->u_salt) === $this->u_password;
        
    }

    /**
     * Generates the password hash.
     * @param string password
     * @param string salt
     * @return string hash
     */
    public function hashPassword($password, $salt)
    {  
        
        return md5($salt . $password);
        
    }

    /**
     * Generates a salt that can be used to generate a password hash.
     * @return string the salt
     */
    protected function generateSalt()
    {
        return uniqid('', true);
    }

    /////////////
    /**
     * 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('u_id', $this->u_id);
        $criteria->compare('u_username', $this->u_username, true);
        $criteria->compare('u_password', $this->u_password, true);
        $criteria->compare('u_salt', $this->u_salt, true);
        $criteria->compare('role_r_id', $this->role_r_id);
        $criteria->compare('u_comment', $this->u_comment, true);
        $criteria->compare('u_created', $this->u_created, true);
        $criteria->compare('u_ban_date', $this->u_ban_date, true);
        $criteria->compare('u_dep', $this->u_dep);
        $criteria->compare('u_sector', $this->u_sector);
        $criteria->compare('ban', $this->ban);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    /**
     * 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 User the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

}
 
Onotole
Сообщения: 1808
Зарегистрирован: 2012.12.24, 12:49

Re: аутентификация, хэш, соли

Сообщение Onotole »

$new_password = $this->u_password;
Конечно будет переписываться
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

уж смотрю в сторону Yii CPasswordHelper . но млин там таже фигня. а как мне быть? нужно при новой записи создавть хэш+соль и при апдейте
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

я почему то думал что $this->u_password - это из базы а $_POST['User']['u_password'] новые присланные пользователем данные.
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

как мне из базы тогда старый пароль получить?
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

нет вы реально шутите? срочно разубедите меня то есть более правильный путь. а то это ппц
//регистрация

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

    protected function beforeSave()
    {
        $new_password = User::model()->findByPk($this->u_id)->u_password;

        if ($this->isNewRecord || $new_password != $_POST['User']['u_password'])
        {
            $this->u_password = $this->hashPassword($this->u_password);
        }

        return parent::beforeSave();
    } 
Onotole
Сообщения: 1808
Зарегистрирован: 2012.12.24, 12:49

Re: аутентификация, хэш, соли

Сообщение Onotole »

А зачем ты вообще в afterfind переопределяешь парль?
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

я почему то думал что $this->u_password - это из базы а $_POST['User']['u_password'] новые присланные пользователем данные.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение ElisDN »

des1roer писал(а):это правильно?
В модели вызывать $_POST не очень хорошо.
des1roer писал(а):вот нашел хороший туториал
Поищите там в комментах ссылку на мою статью об этом же.
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

я по ней первоначально и делал
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение ElisDN »

des1roer писал(а):я по ней первоначально и делал
Не заметно, что Вы делали точно по ней.
Аватара пользователя
des1roer
Сообщения: 391
Зарегистрирован: 2015.02.06, 17:03
Контактная информация:

Re: аутентификация, хэш, соли

Сообщение des1roer »

а вы переписали статью локо? ну я вот по его делал. но мне новый пароль ни к чему. я упростил где мог. а на соль плюнул. хоть и делать там в принципе не много. а пост можно поменять на this->pass. он ведь проходит валидацию в
array('u_username', 'match', 'pattern' => '#^[a-zA-Z0-9_\.-]+$#', 'message' => 'Логин содержит запрещённые символы'),
Ответить