Posts Tagged ‘Software Engineering II’

Very Simple User Authentication with CakePHP

Monday, February 15th, 2010 by Phillip Napieralski

DISCLAIMER: I created this super simple user authentication post for CakePHP version 1.2.7. The latest versions of CakePHP (v2+) have been heavily enhanced. As a side effect, the code in this post will no longer work out-of-the-box. However, I’ll continue to leave this post up as a learning tool. Happy coding!

I’m working with my Software Engineering II class to build an online survey for United Way. I was left in charge to create a simple way to login and authenticate.

The following implementation uses sessions exclusively. I built it so you MUST log-in before accessing any part of the site/survey. You could easily build off this, or even switch to Cake’s built-in ACL and Auth features.

Preliminaries

The database structure presented is the same as in my previous post about a user account class. Here it is again however:

The Login Form View

The login form is extremely simple using Cake’s built in form helper. Here’s how we do it:

<?php
// Pass the model name into the Create function, also pass where the data will be sent
echo $form->create('User', array( 'controller' => 'users', 'action' => 'login' ) );

// Cake automatically knows, based on the input, to create input fields for these two. Cool eh?
echo $form->input('username');
echo $form->input('password');

// Create the submit button
echo $form->end('Login');
?>

That’s much less code, and way clearer once you get used to it. I placed this file in /app/views/users/login_form.ctp

The User Model

<?php
class User extends AppModel {
	function validateLogin($data)
	{
		// Search our database where the 'username' field is equal to our form input.
		// Same with the password (this example uses PLAIN TEXT passwords, you should encrypt yours!)
		// The second parameter tells us which fields to return from the database
		// Here is the corresponding query:
		// "SELECT id, username FROM users WHERE username = 'xxx' AND password = 'yyy'"
		$user = $this->find(array('username' => $data['username'], 'password' => $data['password']), array('id', 'username'));

		if( empty($user) == false )
		{
			return $user;
		}

		return false;
	}
}
?>

This code should go in /app/models/user.php

The Users Controller

<?php
class UsersController extends AppController {
	var $name = 'Users';
	var $helpers = array('Form');

	// Placeholder for login_form, required by CakePHP to see the login_form view
	function login_form() { }

	function login() {
		// Check if they went here after submitting the form
		// Note that all our form data is preceded by the model name ['User']
		if(empty($this->data['User']['username']) == false)
		{
			// Here we validate the user by calling that method from the User model
			if(($user = $this->User->validateLogin($this->data['User'])) != false)
			{
				// Write some Session variables and redirect to our next page!
				$this->Session->setFlash('Thank you for logging in!');
				$this->Session->write('User', $user);

				// Go to our first destination!
				$this->Redirect(array('controller' => 'Controller_name', 'action' => 'Action_name'));
				exit();
			}
			else
			{
				$this->Session->setFlash('Incorrect username/password!', true);
				$this->Redirect(array('action' => 'login_form'));
				exit();
			}
		}
	}

	function logout() {

		$this->Session->destroy();
		$this->Session->setFlash('You have been logged out!');

		// Go home!
		$this->Redirect('/');
		exit();
	}
}
?>

Place this code in /app/controllers/users_controller.php

The AppController – Validate on Every Page

class AppController extends Controller {

	// Check if they are logged in
	function authenticate()
	{
		// Check if the session variable User exists, redirect to loginform if not
		if(!$this->Session->check('User'))
		{
			$this->redirect(array('controller' => 'users', 'action' => 'login_form'));
			exit();
		}
	}

	// Authenticate on every action, except the login form
	function afterFilter()
	{
		if( $this->action != 'login_form' )
		{
			$this->authenticate();
		}
	}
}

Now simply place this code in /app/app_controller.php

What does this do? Well, now no matter where anyone goes on your website, they will be redirected to the login page UNLESS they are logged in! Excellent.