Security::validatePassword gets null $hash argument

Hi. First time post and Yii newbie, trying to finish my first project.

I’m trying to implement the login security, but I’m getting the “Hash is invalid” message from the security object’s validatePassword method. I think the $hash argument is null, but I don’t understand why that is.

In my User object’s validatePassword($password) function, I’m making this standard call:
return Yii::$app->getSecurity()->validatePassword($password, $this->password);

I’m using the NetBeans debugger, and in it, I can see that $this is set to the correct ActiveRecord from my user table, and $this->password is the string “$2y$13$wR50kbDPGeagau1wXPO45uDApsjjUxiKEIXqIp6ZfxsLPpkpoqXxS”. I had earlier created that hash with Yii::$app->getSecurity()->generatePasswordHash($password).

But inside the Security object’s validatePassword($password, $hash) function, the first weird thing is that the debugger is not displaying $hash in the local variable window, although it is showing $password. The test of $hash against the regular expression /^$2[axy]$(\d\d)$[./0-9A-Za-z]{22}/ fails, although the hash string from the database passes the test when I give it to an online regex tester. Finally, when the request finishes and Yii displays the error message, it claims that my user object is calling “yii\base\Security::validatePassword(‘John1’, null)”, as if $this->password was null.

So it seems that my hash value is not getting passed to the Security object’s validatePassword, although the value shows as fine in the debugger. I can’t figure out why it’s not going through.

I’ve got some screenshots, but apparently this forum doesn’t allow attachments.

Update: First off, I just learned that the $hash parameter not being shown in the debugger’s Variables window when null is due to a filter that can be changed. So now I understand that piece of it.

I tried changing my call to
return Yii::$app->getSecurity()->validatePassword($password, '$2y$13$wR50kbDPGeagau1wXPO45uDApsjjUxiKEIXqIp6ZfxsLPpkpoqXxS');

and that works. Could it be that $this->password is prevented from being passed for some reason, for example being thought insecure or something like that?

Hi @JohnBrooking, welcome to the forum.

The most probable cause, IMO, would be that $this->password actually has null when you call validatePassword(). I know that you have already checked it and denied the possibility of $this->password being null, but other things you checked tell us that $this->password is null. So, please double check whether $this is really a user object loaded from the user table.

1 Like

Yes, you are right! Thank you!

What was confusing me is that I already had a Person table and wanted to base my User authentication class from that, instead of having a separate User table. I saw somewhere that it was recommended to have a separate user class extending my base class, Person in this case, so that I could still keep the IdentityInterface separate. So I did that, but neglected to notice that my User class still had its own password property which was masking my Person class password property. In the debugger, though, I could still see Person’s password field in the class *yii\db\BaseActiveRecord*_attributes, and that was correct, along with all the other Person field values. But I didn’t notice the User’s password property higher up in the display, and that one of course was null.

In my defense, with that Netbeans NULL filter on by default, the debugger probably wasn’t even showing the User password property in the Variables window at all, since it was null. No wonder I missed it! Grrrr…

Thanks for making me look more closely!

1 Like