4

I need to create new user. And I want to save password into hash format in DB. But I failed several times.

Here is my code:

Controller

public function actionCreate()
{
    $model = new User();

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->id]);
    } else {
        return $this->render('create', [
            'model' => $model,
        ]);
    }
}

User Model

public function validatePassword($password)
{
    return Security::validatePassword($password, $this->password_hash);
}


/**
 * Generates password hash from password and sets it to the model
 *
 * @param string $password
 */


public function setPassword($password)
{
    $this->password_hash = Security::generatePasswordHash($password);
}

User Table Rules

public function rules()
{
    return [
        [['c_authkey', 'inserttime'], 'required'],
        [['c_branch', 'c_roleid', 'c_active', 'c_status'], 'integer'],
        [['c_expdate', 'inserttime', 'updatetime'], 'safe'],
        [['username', 'c_desig', 'insertuser', 'updateuser'], 'string', 'max' => 50],
        [['password'], 'string', 'max' => 32],
        [['c_authkey'], 'string', 'max' => 256],
        [['c_name'], 'string', 'max' => 100],
        [['c_cellno'], 'string', 'max' => 15],
        [['username'], 'unique']
    ];
}

What I am missing? what's the solution?

  • 1
    You have two return statements (is that a copy+paste error or part of your question?). Remove the first one as it is the one from the demo not using the security component. – Rangad Jun 29 '14 at 15:49
  • It's a part of my question. I removed First one. But it is saving only static password like: 123.. How can I convert them in hash and save to db .. thanks –  Jun 29 '14 at 16:06
  • Then please edit the question to contain the code that is actually causing your problem – Rangad Jun 29 '14 at 16:07
  • thanks. I have edited my question lines. it is saving only static password like: 123.. How can I convert them in hash and save to db. please –  Jun 29 '14 at 16:09
  • What is the name of your password field in the database? – topher Jun 29 '14 at 16:59
  • @topher : password field name is password –  Jun 30 '14 at 03:09

2 Answers2

7

You are saving the unhashed password password instead of password_hash. This can be accomplished using ActiveRecord::beforeSave() to set the password value to password_hash. You should also use a different name for the password field in the form say password_field.

public function beforeSave($insert) {
    if(isset($this->password_field)) 
        $this->password = Security::generatePasswordHash($this->password_field);
    return parent::beforeSave($insert);
}
topher
  • 14,790
  • 7
  • 54
  • 70
  • my user model extending \yii\db\ActiveRecord, but when i use beforeSave method it is not invoking beforeSave() from model, in UserController i'm using $model->save() method – Hitesh Jangid Apr 04 '17 at 12:35
5

Few things are unclear but i hope to give you enough information to resolve your issue and i don't have enough rep to add a comment.

When using the setPassword you will get a string larger than your current VARCHAR(32) setup in the database table. Make it at least VARCHAR(64). Example string that will be returned is $2a$12$FbbEBjZVTLPZg4D/143KWu0ptEXL7iEcXpxJ.MNMl8/6L0SV5FR6u. Adjust this also in your model to make the validation work.

You will need to tell your model to use the password hashing when saving the model.

This example comes from the Yii2/Advanced app. As part of your controller for user creation. They send the request to $model->signup() in the advanced app (Frontend Sitecontroller example)

public function actionSignup()
{
    $model = new SignupForm();
    if ($model->load(Yii::$app->request->post())) {
        if ($user = $model->signup()) {
            if (Yii::$app->getUser()->login($user)) {
                return $this->goHome();
            }
        }
    }

    return $this->render('signup', [
        'model' => $model,
    ]);
}

Adjust your current model to hash the password before saving or add a complete new function, they use 'signup' in the example (Model for signup example). After the model field validation has been successfull they process the request. Change the following fields according to your table.

public function signup()
{
    if ($this->validate()) {
        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->save();
        return $user;
    }

    return null;
}

For debugging validation errors you can add print_r($model->getErrors()); behind any $model->save();

Hope this will give you enough information to get your problem fixed.

Bvlent
  • 71
  • 3