How to hash a password correctly in Yii2 (Getting "Hash is invalid" error)
I am currently experimenting with Yii2 and I am trying to hash the Password of a newly created user. The I think the hashing gets done well, but when I try to login with the user and his newly hashed password I get the Hash is invalid
Error for some reason.
I have checked how to add hashed passwords in yii2 but I can't find a solution working for me.
In my UserController.php
i have the following action:
public function actionCreate()
{
$model = new User();
if ($this->request->isPost) {
if ($model->load($this->request->post()) && $model->save()) {
\Yii::$app->security->generatePasswordHash($model->password);
return $this->redirect(['view', 'id' => $model->iduser]);
}
} else {
$model->loadDefaultValues();
}
return $this->render('create', [
'model' => $model,
]);
}
And in my User.php
model I use the following function to validate the password:
public function validatePassword($password) {
if(is_null($this->password)) {
return false;
}
return Yii::$app->getSecurity()->validatePassword($password, $this->password);
}
Anyone can tell me what I am doing wrong? Because I can't see what I am missing here.
Solution 1:
You are saving unhashed password with $model->save()
.
The \Yii::$app->security->generatePasswordHash($model->password)
creates password hash and returns it. But you are not using returned hash in any way.
You need to load data into model, set the hashed password in password
attribute of model and then save the model:
if ($this->request->isPost) {
if ($model->load($this->request->post())) {
$model->password = \Yii::$app->security->generatePasswordHash($model->password);
if ($model->save()) {
return $this->redirect(['view', 'id' => $model->iduser]);
}
}
}
You can also override load()
method to hash password right after data are loaded.
class User extends ActiveRecord implements IdentityInterface
{
public function load($data, $formName = null)
{
$result = parent::load($data, $formName);
//only hash password if it was changed
if ($result && $this->isAttributeChanged('password')) {
$this->password = Yii::$app->security->generatePasswordHash($this->password);
}
return $result;
}
// ... other definitions ...
}