CakePHP 2: Override AuthComponent's "password" method

authentication, cakephp, passwords

Solution

You could probably create a custom auth object and hash the password however you like. Take a look at the existing auth objects to get the general idea of how they work.

Problem

My goal is to have a unique salt for each user rather than just using `Configure::read('Security.salt')` for every user. I know that CakePHP 2.x no longer hashes passwords automatically. This allows me to perform model validation on passwords, which is very nice. However, I don't see a way that I can override the AuthComponent's "password" method. So even though I can control how passwords are hashed before they are saved to the database, I cannot control how passwords are hashed when performing the actual login. From the cookbook: You don’t need to hash passwords before calling `$this->Auth->login()`. What can I do to make `$this->Auth->login()` use a custom method of password hashing? Thanks. UPDATE: I ended up going with dr Hannibal Lecter's answer (creating a custom authentication object). Here's how to do it: Old code: ``` $this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email'))); ``` New code (change "Form" to "Custom"): ``` $this->Auth->authenticate = array('Custom' => array('fields' => array('username' => 'email'))); ``` Create "app/Controller/Component/Auth/CustomAuthenticate.php" and make it look like this: ``` <?php App::uses('FormAuthenticate', 'Controller/Component/Auth'); class CustomAuthenticate extends FormAuthenticate { } ``` Copy the "_findUser" and "_password" methods from "lib/Cake/Controller/Component/Auth/BaseAuthenticate.php" and paste them into the "CustomAuthenticate" class. Then make the following two modifications to the "_findUser" method: Remove this line from the "$conditions" array: `$model . '.' . $fields['password'] => $this->_password($password),` Change `if (empty($result) || empty($result[$model])) {` to `if (empty($result) || empty($result[$model]) || $result[$model][$fields['password']] != $this->_password($password, $result[$model]['id'])) {` Then make the following two modifications to the "_password" method: Create the "$id" parameter by changing `protected function _password($password) {` to `protected function _password($password, $id) {` Update the salt value by changing `return Security::hash($password, null, true);` to `return Security::hash($password, null, Configure::read('Security.salt') . $id);` Lastly, update all occurrences of `AuthComponent::password` to use `Security::hash` with the same logic as above.

Original source