问题
I'm trying to set up a form to allow a user to change their password using CakePHP 2.3. The algorithm being used is blowfish. I have the following three fields:
<?php echo $this->Form->input('old_password', array('type' => 'password', 'autocomplete' => 'off')); ?>
<?php echo $this->Form->input('new_password', array('type' => 'password', 'autocomplete' => 'off')); ?>
<?php echo $this->Form->input('new_password_confirm', array('type' => 'password', 'autocomplete' => 'off', 'label' => 'Confirm Password')); ?>
Here is the code where I'm trying to verify they entered their old password correctly:
$hash = Security::hash($this->request->data['User']['old_password'], 'blowfish');
$correct = $this->User->find('first', array(
'conditions' => array(
'User.id' => AuthComponent::user('id'),
'User.password' => $hash
),
'fields' => array('id')
));
The problem is that even though I type in the old password correctly, Cake never finds the user because it doesn't seem to be calculating the correct hash. Each time I submit the form with the same old password, Cake generates a different hash every time. This is likely due to my lack of understanding of how the blowfish/bcrypt algorithm works, but I can't seem to figure it out.
What am I missing here?
回答1:
Working with blowfish hashes is different than with other hash types. From the API docs of the hash method:
Comparing Hashes: Simply pass the originally hashed password as the salt.
This means in your case you first have to retrieve the hashed password for the specific user and then use it as the salt. Something like
$user = $this->User->find('first', array(
'conditions' => array(
'User.id' => AuthComponent::user('id')
),
'fields' => array('password')
));
$storedHash = $user['User']['password'];
$newHash = Security::hash($this->request->data['User']['old_password'], 'blowfish', $storedHash);
$correct = $storedHash == $newHash;
回答2:
Is Easy add in Models for example Users.
Link source: https://bitbucket.org/snippets/eom/arzxR
/**
* Users Model
*/
class Users extends AppModel
{
.........
public function beforeSave($options = array()) {
parent::beforeSave($options);
// Save new password is exist..?
if (isset($this->data[$this->alias]['password'])==true) {
// Security bcrypt Blowfish
App::uses('Security', 'Utility');
$hash = Security::hash($this->data[$this->alias]['password'], 'blowfish');
$this->data[$this->alias]['password'] = $hash;
}
return true;
}
public function password_check($user_id = null, $password_check = null) {
// Get password old
$hash_old = $this->field('password',array('id'=>trim($user_id)));
// Security bcrypt Blowfish
App::uses('Security', 'Utility');
$hash_new_check = Security::hash($password_check, 'blowfish', $hash_old);
// Son iguales
if($hash_new_check == $hash_old){
return true;
}
return false;
}
public function password_update($user_id = null, $password_new = null) {
// Update new password
if($this->save(array('id'=>$user_id, 'password'=>$password_new))){
return true;
}
return false;
}
.........
}
来源:https://stackoverflow.com/questions/17251814/changing-password-with-cakephp-and-blowfish