Posts Tagged ‘Software Engineering II’

Very Simple User Authentication with CakePHP

Monday, February 15th, 2010 by Phillip Napieralski

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.