Secure CakePHP via Sessions & Magic (Login / Logout)

Making sure a CakePHP application is secure is a total snap thanks to “sessions” – the rock animal of websites. Put on your All-Stars and boot up your MacBook – I’m about to go Discovery Channel on your ass.

Hopefully by the end of reading this article, you’ll be able to create a secure CakePHP application. The point is to allow only registered users access to restricted areas of your application without blocking access to all areas of your application.
Pretext
We’ll be creating three sections in order to achieve our goal of total security:

1: /app/app_controller.php
2: /app/controllers/users_controller.php
3: /app/views/users/
-> add.thtml, edit.thtml, index.thtml, login.thtml, logout.thtml

As always, all of these sections can be downloaded so you can follow along.
1. The app_controller
Our app_controller.php file will hold the function checkSession which will check session data to make sure a user is logged in. Here’s the function in its entirety:

function checkSession(){

// fill $username with session data
$username = $this->Session->read('user');

// if the $username is empty,
// send user to login page
if (!$username){
$this->redirect('/users/login');
exit();
} else {
// if $username is not empty,
// check to make sure it's correct
$results = $this->User->findByEmail($username);

// if not correct, send to login page
if(!$results){
$this->Session->delete('user');
$this->Session->setFlash('Incorrect session data.');
$this->redirect('/users/login');
exit();
}

// otherwise set $user variable as users email address
$this->set('user', $results['User']['email']);
}
}
/pre>

The commenting throughout the above code is pretty self-explanatory - the session data is checked and validated. Score one for us.
2. The users_controller

Of the six functions in users_controller.php, we'll cover the login function. It's purpose is to check user-submitted data against a database, and either set a session (success) or redirect the user to the login page (failure) for another login attempt.

function login() {
$this->set('error', false);
if ($this->data) {
// check submitted email address against database
$results = $this->User->findByEmail($this->data['User']['email']);
if ($results && $results['User']['password'] == md5($this->data['User']['password'])) {
// set "user" session equal to email address
$this->Session->write('user', $this->data['User']['email']);
// set "last_login" session equal to users last login time
$this->Session->write('last_login', $results['User']['last_login']);
$results['User']['last_login'] = date("Y-m-d H:i:s");
// save last_login date
$this->User->save($results);
$this->redirect('/');
} else {
// login data is wrong, redirect to login page
$this->Session->setFlash('Wrong username / password. Please try again.');
$this->redirect('/users/login');
}
}
}

The commented code above should be enough to grasp an understanding of how $this->Session works. It's a simple CakePHP method of setting/deleting/reading sessions.
Secure Your Gear
Now that you've got the code to secure your Cake pages, you need to use it. Call the checkSession function to whenever you'd like to require a user to be logged in.

<?php
class ExampleController extends AppController {
var $name = "Example";
var $helpers = array('Html');

function index() {
// make sure we're logged in
$this->checkSession();

// when viewing /app/views/examples/index.thtml
// the user will be redirected to the login page
// unless he's logged in, in which case he'll
// see the page as normal
}

function example() {
// when viewing /app/views/examples/example.thtml
// everyone (logged in or not) will see this page
}
}
But what if you want to secure all the pages in a controller? Simple! Use Cake's beforeFilter function:

<?php
class ExampleController extends AppController {
var $name = "Example";
var $helpers = array('Html');

function beforeFilter() {
$this->checkSession();
}

function index() {
// when viewing /app/views/examples/index.thtml
// the user will be redirected to the login page
// unless he's logged in, in which case he'll
// see the page as normal
}

function example() {
// when viewing /app/views/examples/example.thtml
// the user will be redirected to the login page
// unless he's logged in, in which case he'll
// see the page as normal
}
}

Download The Package
Make sure you grab the complete package to see working examples of this article. A .sql file has been included for easy setup of the required MySQL users table.
Download the 'Secure CakePHP via Sessions' package and consider yourself cool.