CakePHP user/password/authentication manager: the missing guide

1 Oct

CakePHP has excellent documentation on its site on how to do authentication – its actually quite complete, you can just copy-paste and drop in the code into your build and get a working authentication system. The problem is: it doesn’t quite tell you how to handle adding/editing users and particularly their passwords from a UI perspective. There are plugins out there, like CakeDC’s Users plugin, which I haven’t tried, but if you want to stay lightweight and write your own code, here’s a guide.

I wanted to have a UI system on the backend that allowed me to create and edit users, and set/reset their passwords in a manner similar to how its done with most professional sites these days:

  • Enter the password twice for creating a user
  • Enter password twice for editing a user, but blank password means password is unchanged

With this in mind, I made a few changes to the users models, controllers and views.

1. MODEL VALIDATION

First of all, I changed the validation code for the users.php model to the following:

	var $validate = array(
// other validation code
		'password1' => array(
			'notempty' => array(
				'rule' => array('notempty'),
			),
		),
		'password2' => array(
			'notempty' => array(
				'rule' => array('notempty'),
			),
		),
	);

Basically removing all hints of the “password” field. Why? As you will see later, I’ve removed any sort of “view” or direct access to the password in the views and controller.

2. VIEWS CHANGE FOR ADD/EDIT

Next for the views, I made these changes to the add and edit views.

I replaced

		echo $this->Form->input('password');

on both of them with these lines:

add.ctp

		echo $this->Form->input('password1', 
			array('label' => 'Password',
				'type' => 'password')
		);
		echo $this->Form->input('password2', 
			array('label' => 'Password (again)',
				'type' => 'password')
		);

edit.ctp

		echo $this->Form->input('password3', 
			array('label' => 'Password',
				'type' => 'password')
		);
		echo $this->Form->input('password4', 
			array('label' => 'Password (again)',
				'type' => 'password')
		);

Why password1 and password2 for add.ctp, and password3 and password4 for edit.ctp ? Because as you might remember from the model, password1 and password2 are validated – which means anyone using the UI MUST enter the password for the field. Changing the fieldnames makes it easy for the edit view – so people can leave those fields blank.

3. CONTROLLER CHECKS FOR PASSWORD

Finally, the controller. Here is how to handle the add() method. Between these lines:

	function add() {
		if (!empty($this->data)) {
			// add following code here
			$this->User->create();

add these lines:

			if (!($this->data['User']['password1'] === 
				$this->data['User']['password2'])) {
				$this->Session->setFlash(__('Passwords do not match.', true));				
				return;
			}
			$this->data['User']['password'] = 
				$this->Auth->password($this->data['User']['password1']);

For edit(), its a little trickier since you want to check for blank passwords, and if so, leave the user password unchanged.

	function edit($id = null) {
		... ...
		if (!empty($this->data)) {
			// add following code here
			if ($this->User->save($this->data)) {

add these lines:

			// Passwords do not match
			if (!($this->data['User']['password3'] === 
				$this->data['User']['password4'])) {
				$this->Session->setFlash(__('Passwords do not match.', true));				
				return;
			}
			// If the password is left blank, 
			// just reuse the existing password
			if (strlen($this->data['User']['password3']) == 0) {
				$User = $this->User->read(null, $id);
				$this->data['User']['password'] = $User['User']['password'];
			} else {
				$this->data['User']['password'] = 
					$this->Auth->password($this->data['User']['password3']);
			}

And that’s it!!! A professional UI for adding users, combined with CakePHP’s great in-built authentication system!

UPDATE: Oct 1, 1930 EST: In order to view the username and provide a logoff option add this to app_controller.php to provide the variable to all your views:

	function beforeRender() { 
		$this->set('trUsername', $this->Auth->user("username")); 
	} 

and this line to somewhere in your views:

	<p class="login">Logged in as <b><? echo $trUsername ?></b>
	[<?php echo $this->Html->link(__('logout', true), array('controller' => 'users', 'action' => 'logout')); ?>]
	</p>
Advertisements

3 Responses to “CakePHP user/password/authentication manager: the missing guide”

  1. Vivek October 4, 2011 at 12:00 am #

    Hmm, it would be interesting if you could post the UI screenshot too. I’m playing around tweaking WordPress trying to figure out how to create a regular front end for users to sign in/register and post to different categories as opposed to accessing the regular WP backend for authors.

    • sumanrs October 4, 2011 at 10:52 am #

      Hi, by screenshots, do you mean for UI or code? Actually, mine is a really simple script – in fact, I ended up going with CakeDC’s Users plugin eventually – I realized I would have to built a lot of the code myself and opted for the existing plugin. I had to customize it quite a bit, but it does what I need it for.

      If you are integrating with WordPress, you might have to set the table prefix in CakePHP and make sure to get the correct groups from the user table to allow for the right ACL access. That might be a little bit of work… have you looked at various WordPress ACL plugins? There are a few good ones out there.

  2. Vivek October 4, 2011 at 4:05 pm #

    Appreciate your response Suman. Yeah I actually meant the UI.
    I’m running WordPress plus buddypress and I am trying to create a social bookmarking based site (like Delicious, Digg). Only the admin will manage users/rights , so I don’t need a front end UI to add /edit users or configure rights. But I need a front end UI for regular users who can simply post URLS into different WP categories (like in Digg, Delicious). By default, WP login redirects users to WP dashboard.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: