Yii user login system with password rehashing

2019-09-07 08:07发布

I am using Yii framework and I want to create a user login system with rehashing passwords. so when user loges in system geerates new salt and rehashes the password with new salt. I am getting no errors but when I am checking password and salt they don't change in database. so here is what I have done for now:

<?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
{
    private $_id;

    public function authenticate()
    {
        $record=User::model()->findByAttributes(array('username'=>$this->username));
        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if($record->password !== hash('sha512', $this->password.Security::Decrypt($record->salt)))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            while ($record2 !== null){
                $salt = Security::GenerateSalt(128);
                if ($salt === null)
                {
                    die('can\'t generate salt');
                }
                $record2 = User::model()->findByAttributes(array('salt'=>Security::Encrypt($salt)));
            }
            $record->salt = Security::Encrypt($salt);
            $record->password = hash('sha512', $this->password.$salt);
            $record->save();
            $this->_id=$record->id;
            $this->setState('user_id', $record->id);
            $this->setState('user_username', $record->username);
            $this->setState('user_privilages', $record->privilages);
            $this->errorCode=self::ERROR_NONE;
        }
        return !$this->errorCode;
    }

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

1条回答
成全新的幸福
2楼-- · 2019-09-07 08:40
  1. Use authenticate only to authenticate and return success or failure status
  2. Use the AfterLogin method in the CWebUser class to perform the rehashing and make sure you do it only when authorized from username/password and not from cookie.

Your webuser class would look like this:

protected $plain_password;

public function login( $identity, $duration = 0)
{
    // ...
    $this->id = $identity->id;
    $this->plain_password = $identity->password;
    return parent::login($identity, $duration);
}

protected function afterLogin($fromCookie)
{
    $this->updateUserDataOnLoginSuccess($fromCookie);
    return parent::afterLogin($fromCookie);
}

/**
* If the user logged in successfuly, we should update some data about him, like the last login time
* @param bool $fromCookie indicates whether the login takes place using cookie or login form
*/
private function updateUserDataOnLoginSuccess($fromCookie)
{
    $attributes = array('last_login' => new CDbExpression('NOW()'));

    if(!$fromCookie)
    {
        $atrributes['hash'] = new hash;
        $attributes['password'] = new hashedpassword($this->plain_password, $atrributes['hash']);
    }

    User::model()->updateByPk($this->id, $attributes);
}
查看更多
登录 后发表回答