Yii2 Login from DB (Setting unknown property: app\models\User::password_hash)

user3640056 picture user3640056 · Apr 1, 2015 · Viewed 13.7k times · Source

I want the user authentication in Yii to be based on user table in my database. This is my User model:

<?php

namespace app\models;

use Yii;
use yii\base\NotSupportedException;
use yii\db\ActiveRecord;
use yii\helpers\Security;
use yii\web\IdentityInterface;


/**
 * This is the model class for table "user".
 *
 * @property integer $id
 * @property string $username
 * @property string $password
 * @property string $title
 */
class User extends \yii\db\ActiveRecord implements IdentityInterface
{


    public static function tableName()
    {
        return 'user';
    }



    /**
     * @inheritdoc
     */

    public function rules()
    {
        return [
            [['username', 'password'], 'required'],

            [['username', 'password'], 'string', 'max' => 100]           

        ];
    }



    /**
     * @inheritdoc
 */

    public function attributeLabels()
    {
        return [
            'id' => 'UserID',
            'username' => 'Username',
            'password' => 'Password',

        ];

    }   

    public static function findIdentity($id) {

        return static::findOne($id);
    }

    public static function findIdentityByAccessToken($token, $type = null) {
        return static::findOne(['access_token' => $token]);
    }

    public static function findByUsername ($username){

        return static::findOne(['username' => $username]);

    }
    public static function findbyPasswordResetToken($token)
    {
        $expire= \Yii::$app->params['user.passwordResetTokenExpire'];
        $parts = explode('_', $token);
        $timestamp = (int) end($parts);
        if ($timestamp + $expire < time()) {
            //token expired
            return null;

        }
        return static::findOne(['password_reset_token' => $token ]);


    }

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

    public function getAuthKey() {
        return $this->auth_key;
    }

    public function validateAuthKey($authKey) {
        return $this->getAuthKey() === $authKey;
    }

    public function validatePassword($password){
        $this->password_hash= Yii::$app->security->generatePasswordHash ($password);
    }
    public function generateAuthKey()
    {
        $this->auth_key = Yii::$app->security->generateRandomKey();
    }

    /**
     * Generates new password reset token
     */
    public function generatePasswordResetToken()
    {
        $this->password_reset_token = Yii::$app->security->generateRandomKey() . '_' . time();
    }

    /**
     * Removes password reset token
     */
    public function removePasswordResetToken()
    {
        $this->password_reset_token = null;
    }



}

But it is giving me this error when I try to login:

Setting unknown property: app\models\User::password_hash

This is actionLogin in siteController:

public function actionLogin()
    {
        if (!\Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

And this is the code in LoginForm.php:

  public function validatePassword($attribute, $params)
    {
        if (!$this->hasErrors()) {
            $user = $this->getUser();

            if (!$user || !$user->validatePassword($this->password)) {
                $this->addError($attribute, 'Incorrect username or password.');
            }
        }
}

/**
 * Logs in a user using the provided username and password.
 * @return boolean whether the user is logged in successfully
 */
public function login()
{
    if ($this->validate()) {
        return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
    } else {
        return false;
    }
}

I don't know what is wrong, could you please help me fix this?

Answer

Balaji Viswanath picture Balaji Viswanath · Apr 1, 2015

This is because the column "password_hash" assigned in the function "validatePassword()" doesn't exist in database or is not declared in the User model.

If the password hash is stored in the database in "password" field, then change "validatePassword()" to,

public function validatePassword($password)
{
    return $this->password === Yii::$app->security->generatePasswordHash ($password);
}