I have a user edit View. When people access this view it has the hashed password in the password block.
If you click save, it (obviously) hashes the password again, due to this being in my User model.
public function beforeSave($options = array()) {
if(!empty($this->data['User']['password'])) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
return true;
}
But I don't want to have it hashed twice (because it means the password has changed). I changed the edit view and added array('value' => '','autocomplete'=>'off')
to the password field. Now when I save it, it saves a blank string in the database. I thought that it prevents it from doing that with the if(!empty($this->data['User']['password']))
statement in the beforeSave
function.
How would I prevent the password from being double hashed?
Solution is fairly simple. Simply change the if statement in beforeSave from:
public function beforeSave($options = array()) {
if(!empty($this->data['User']['password'])) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
return true;
}
to:
public function beforeSave($options = array()) {
if(!empty($this->data['User']['password'])) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
} else {
unset($this->data['User']['password']);
}
return true;
}
Compare the hashes:
You can compare the hash saved in the database against the text in the password field. If you haven't touch the password (changed the password field), the hashes should match. Let's say your saved hash is xyz
, and the hash loaded in the password hash is still untouched, xyz
; in this case you don't have to rehash anything, and the hashes should remain the same.
In the other case, let's say your saved hash is xyz
, but you edited the password html field to be abc
; in this case you will have to rehash the new password (abc
) and then replace the old one you have in the database record.
All of this can be translated in code as follows:
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
if(isset($this->data[$this->alias]['id'])) {
$id = $this->data[$this->alias]['id'];
$user = $this->findById($id);
} else {
$id = false;
}
if(!$id || $this->data[$this->alias]['password'] != $user['User']['password']) {
$passwordHasher = new SimplePasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
}
return true;
}
Regards, M
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With