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']);
}
}
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.

maybe you could a little plugin with it :)
http://manual.cakephp.org/chapter/plugins
More fine-grained control can be obtained using ACL, which is described in the cake manual (applicable to 1.1) and numerous tutorials (1.1 & 1.2, YMMV).
Thanks a lot man, works like a charm :)
It works very well! :) Thanks
Hi,
is this also running on cakephp 1.2 version?
Yes this works on cakephp 1.2
You should add some salt to the md5 :)
and add ’somesalt’ when you create the user’s record (add action for eg.)
I am still a beginner of this,i find difficulty in understanding it..
I downloaded the package but errors are coming out..Please help me with this.
Please explain me why are there errors? What’s wrong with this?
The code works very well, thanks a lot!
jdm,
I’m not sure, but it seems like you are using the wrong version of CakePHP. There are certain tasks that were moved from the html helper to the form helper, I am a beginner too so I may be 100% wrong, but those warnings look like the ones I got when I went from Cake 1.1 to Cake 1.2. The helpers should be there, you just may have to replace $html-> with $form->. Again, I may be wrong, but give it a try.
jdm: You are probably using Cake 1.2 (which has new form helpers) while this is written for 1.1.
Thanks 4 letting me about helpers….
Hi
I must say that i’m pretty confused. I treid to work with session&cakephp&redirect and I always ended with erased sesion after redirecting to another controler.
Although, what do you think about putting some nice ” exit();” after
$this->redirect? consider that beacuse when you are redirecting the script is still working