Simple User Registration in CakePHP 1.2, Part II

I got a question in the comments about my previous post on simple user registration about how to do some of the necessary validation for registration in the model. I thought I'd show some code I did to do exactly that.

The key to all this stuff is using a second form field for doing the validation. Here's some sample code for you, based on the latest straight-from-svn version of Cake PHP 1.2 (r6402)

PHP:
  1. <?php
  2.  
  3. /**
  4. * Class used for user authentication on the league website
  5. *
  6. */
  7.  
  8. class User extends AppModel
  9. {
  10.     var $name = 'User';
  11.  
  12.     var $validate = array(
  13.         'id' => array('rule' => 'blank',
  14.                       'on' => 'create'),
  15.         'username' => array('rule' => 'alphanumeric',
  16.                             'required' => true,
  17.                             'message' => 'Please enter a username'),
  18.         'password' => array('rule' => array('confirmPassword', 'password'),
  19.                             'message' => 'Passwords do not match'),
  20.         'password_confirm' => array('rule' => 'alphanumeric',
  21.                                     'required' => true)
  22.     );
  23.  
  24.     function confirmPassword($data) {
  25.         $valid = false;
  26.        
  27.         if ($data['password'] == Security::hash(Configure::read('Security.salt') . $this->data['User']['password_confirm'])) {
  28.             $valid = true;
  29.         }
  30.        
  31.         return $valid;
  32.     }
  33.  
  34. }
  35. ?>

So, let's talk about what's in there.

  • make sure that the username is alphanumeric and has been entered
  • make sure the password exists and run the custom validation function 'confirmPassword' on the data being posted in
  • make sure that our confirm password field exists and is alphanumeric

The only tricky thing when I made this was figuring out how to compare the two password fields, and where to get the proper hashing from. Initially I thought that I could somehow import the Auth component in there but a quick chat with gwoo showed me how stupid that was when I could just duplicate how the component itself is hashing the password field. That's what is going in with the use of Security::hash(...).

Hope that helps.

Article Tags >> ||

Simple User Registration in CakePHP 1.2

In the comments for my seemingly-popular post about using CakePHP's Auth component (available in CakePHP 1.2), people have been having some questions about how the password is hashed and questions about a user registration system. Of course, the snarky response is "go and read the source for Security::Hash() and create some of your own code", but it is easier to just give people some code so they stop asking.

I'm in the process of building out an admin area for my simulation baseball league web site, and I created a registration system. Here's a condensed version of it.

First, I have my User model

PHP:
  1. <?php
  2. class User extends AppModel {
  3.  
  4.     var $name = 'User';
  5.     var $useTable = 'users';
  6. }

Next, I created my controller for my users and the registration action for it

PHP:
  1. class UsersController extends AppController {
  2.     var $name = 'Users';
  3.     var $helpers = array('Html', 'Form');
  4.     var $components = array('Auth');
  5.    
  6.     function beforeFilter() {
  7.         $this->Auth->allow('register');
  8.     }
  9.        
  10.     function register() {
  11.         if (!empty($this->data)) {
  12.             if ($this->data['User']['password'] == $this->Auth->password($this->data['User']['password_confirm'])) {
  13.                 $this->User->create();
  14.                 $this->User->save($this->data);
  15.                 $this->redirect(array('action' => 'index'));
  16.             }
  17.         }
  18.     }
  19. }

So, let's dissect this controller:

  • We're using the Auth component, set via "var $components = array('Auth')"
  • We tell Auth to not ask for authentication when doing the 'register' action
  • When we detect data coming into the 'register' action (usually via a POST), then check to see if the hashed password that Auth has created from the 'password' field in our form matches the hashed value of the 'confirm password' field from our form
  • If all that is okay, we create and save our new user record

Yes, it really is that easy.

The form for this is very simple as well

PHP:
  1. <?php
  2. echo $form->create('User', array('action' => 'register'));
  3. echo $form->input('username');
  4. echo $form->input('password');
  5. echo $form->input('password_confirm', array('type' => 'password'));
  6. echo $form->submit();
  7. echo $form->end();
  8. ?>

Throw all that stuff together and you now have a very simple user registration system.

Article Tags >> ||

Follow-up to “A Hopefully Usefull Tutorial For Using CakePHP’s Auth Component”

There have been some mention in the comments for this post for clarification on the 'remember me' cookie that is mentioned in the code. I thought I'd elaborate a bit on how I used it for this example.

As part of a project I was working on while at CDC there was a requirement for there to be 'Remember Me' functionality for the authentication system. I'm sure you've seen this elsewhere. Implementing such a thing is actually very simple, but I should've clarified that 'remember me' functionality is NOT part of the Auth component.

  • When they go to log in, check to see if there is a 'remember me' cookie present.
  • If there is, read in the cookie (containing the user name and encrypted password. Never EVER put plaintext passwords in a cookie!) and then compare those values to the database table (or whatever data source you are using) that you are authenticating against. If they match, then set the user as being 'authorized' and they can proceed on their merry way. Otherwise, delete the cookie (it may be a bad cookie) and send them to the login screen

  • If there is no cookie, let the person log in as usual and if they are successfully authenticated then store that information in your 'remember me' cookie before you let them proceed to whatever areas require authorization.

Now, to drop into CakePHP for a minute the key thing that was left out of the previous blog posting is *how* you get the Auth system to accept the values in the cookie. It took a quick IM conversation with gwoo to jog my memory.

PHP:
  1. function beforeFilter() {
  2.      /**
  3.      * Code that does other Auth stuff goes before this...
  4.      */
  5.  
  6.      /**
  7.      * If you've checked the data against your auth model,
  8.      * you have to put that info into $this->data so that the
  9.      * Auth component can use it
  10.      */
  11.      $this->data['User']['username'] = $cookie['username'];
  12.      $this->data['User']['password'] = $cookie['password'];
  13. }

The password stuff is critical here. By default, the Auth component will take any password that you've entered via a form and then hash it using the default for Auth (this value is configurable, check the Auth section API to see how to do it). So, make sure that the *encrypted* password value is being placed into $this->data, and consequently stored in your cookie. In the example above 'User' is the model being authenticated against, so feel free to change it if you're using something else. Keep in mind it's probably not a good idea to put a field called 'password' in your cookie, so feel free to change it to something less obvious or come up with another method of obscuring the true contents of the cookie.

Hope that clears up the 'remember me' cookie mystery for people. Thanks again to gwoo for helping me rummage around in my brain for the details.

Article Tags >> || ||
Want to advertise on this blog? Send email to chartjes@littlehart.net
GTcars Canadian Car Audio TurboDodge Car For Sale Sign
Audi Forum Mustang Forum Dodge Intrepid Miata Turbo
GTscene Pontiac Bonneville