Auth Component: Using hashPasswords
Created: 2008-02-24 19:32:43, last updated: 2008-02-24 19:54:45
If you have used Cake's Auth Component, you should know that it hashes your password field from your Auth's model name automatically. So, when you make some sort of confirmation password in your accounts creation, you have to make something like this to validate your password:
Extracted from Chris Hartjes blog: Simple User Registration in CakePHP 1.2, Part II
if ($data['password'] == Security::hash(Configure::read('Security.salt') . $this->data['User']['password_confirm'])) { $valid = true; }
With my friend mozart_ar, we consider that there should be lesser weird way of doing it. We thought password hashing should be either in the model or the controller, but not in both. Hopefully, Cake's Auth Component give us the possibility of doing this in a clean way: using the authenticate attribute of the Auth Component.
The authenticate attribute accepts an object reference. Then, it checks if a hashPasswords function exists in that reference. If exists, calls our custom hashPasswords function. For example, in your User Model you can create:
class User extends AppModel { // Your code function hashPasswords($data) { if( isset($data[$this->name]['password']) ) { $data[$this->name]['password'] = $this->hashString( $data[$this->name]['password'] ); } if( isset($data[$this->name]['password_confirmation']) ) { $data[$this->name]['password_confirmation'] = $this->hashString( $data[$this->name]['password_confirmation'] ); } return $data; } function hashString( $string ) { return Security::hash(Configure::read('Security.salt') . $string ); } }
Now for this to work, you must pass a User's model reference to the Auth Component. You can put this in the app_controller.php, but you should need to create an object reference of the User Model in every action of your controller. As you generally will use this functionality in your users/register or users/add action, you can put this in your UserController:
class UsersController extends AppController { // Your code... function beforeFilter() { $this->Auth->allow('login', 'logout', 'register'); $this->Auth->authenticate = $this->Account; parent::beforeFilter(); } // Rest of your actions }
So now when checking passwords equality you just do:
if ($data['password'] == $this->data['User']['password_confirm']) { $valid = true; }
Other useful resources:
I hope you like this lovely use of this Auth Component feature as much as I do.
1 comment
Baz2008-06-06 11:44:01
I've never noticed this in the Auth component until today.
I've found other ways around this problem, but you way seems a lot cleaner.