Good Friday to all. Over the past several weeks I have been working a lot with the AuthComponent in CakePHP and have learned a couple of lessons that I wanted to share with you all.
The title calls them “flaws”, but I suppose this isn’t completely accurate, it depends how you look at it. To me they are flaws because I assumed the AuthComponent worked one way, only to find out different.
The three flaws I found are:
Blank passwords being hashed
The first flaw is what I discussed in my last post regarding isset(). The AuthComponent has an if statement that says “if the username is set and the password is set” the password should be hashed.
In my post I discuss how isset is returning true when the password field has no data in it. This caused me a few problems because my password validation was never being met! I would submit the form and the password field would come back populated with 32 characters hashed from a blank form field.
My fix for this was to simply update the if statement described above to use a !empty() instead of an isset() around the password field.
Not hashing passwords because the password field is not in the “model” of the Auth
This is an interesting one. The reason I discovered it is I have a system where we need three different logins. Regular users, providers, and admins. I had to use three different tables because each store varying information.
In my app_controller.php I’ve setup a case statement to determine which model and controller to use for the login. I do not know if this is the best solution, but I found it worked quite well for my purpose.
The problem that I noticed was, when I baked all of my models, controllers, and views, for the users and providers table I also chose to setup the admin routing.
When you are logged in as an admin and adding or editing users, the password field was not automatically being hashed as it does when I’m adding or editing an admin account.
This is not a major flaw, but something I had not accounted for. So I had to update my admin_add and admin_edit functions in the users_controller.php and providers_controller.php to hash the password for me.
Not hashing passwords because the username field is not in the form
I seem to have a knack for finding weird issues. I was tasked with creating a “lost password” form. Because we are using the AuthComponent and the default hash md5’s the results, we couldn’t create a standard lost password form that would email the password. We had to build a process that would allow the user to reset their password.
The process I created was, a form to collect the email address. An email would be sent with a link containing a key that would be validated against the account to ensure it was them and allow them to reset their password.
When you click the link and it validated successfully, a form would be displayed with a password and confirm password field to enter your new password.
Again, like the issue above, the password was not automatically encrypted when the form was posted.
There are two solutions to this problem, either add the username field to the form as a hidden field or like above, hash the password yourself.
I chose the former because I needed the email address as part of my secret key.
Even with these three flaws, I still love the CakePHP AuthComponent. It saves a lot of time in setting up an authentication system. I’m not sure what to do about my three issues in regards to submitting bug fixes or not because I’m not sure if they necessarily are a bug or not. Hopefully, I have helped anyone who has run into a similar issue.

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 
Firstly, if it was me, I would have had one Users table which stored id,name,password and then 3 hasOne tables (Regulars, Admins, Providers) for each user types unique information.Secondly, the trick to dealing with the hashing of blank passwords is not to include the ‘password’ field in the form, but to call it something else, e.g new_password.
The logic for your admin_add() then looks something like:
function admin_add() {
if ($this->data) {
$this->User->create();
$this->data['User']['password'] = $this->Auth->password($this->data['User']['new_password'];
if ($this->User->save($this->data) {
//saved
}
else {
// validation error
}
}
}
The validation for the User can then compare new_password and confirm_password without any problems as neither is hashed:
Using the same idea, it’s a lot simpler to write the change password & password reset methods.
Hope this helps
No, there is an easy way around this, if you authorize the model, this allows you to then check the password out prior to the Auth component hashing the password. It actually kind of destroys all 3 of your flaws.Check it out in teknoids blog here
http://teknoid.wordpress.com/2008/10/08/demystifying-auth-features-in-cakephp-12/
empty() will give you a notice level error on the variable being tested if it is not set, hence isset().good article , I added you in the ‘Liked’ category.. thanks for sharing the article!Wow, this is very useful.. Thanks for sharing this and hoping I could implement it too.rqvfwweg…rqvfwweg…
I liked the article. One thing you didn’t described that where to use empty() instead of isset(). which file ? in auth component or into user_controller with registration() action?Can you explain with one example? or some where it is shown?