Very Simple User Authentication with CakePHP
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.


March 27th, 2010 at 5:56 PM
Shouldn’t the login form be in the users subdirectory and be called login_form.ctp?
March 27th, 2010 at 11:42 PM
Fixed! Thanks for pointing that out.
July 24th, 2010 at 2:21 PM
i need to make authentication for two different users……one for user(when logged in should be directed to user page) and another for admin(directed to admin page). pls help me out. thanks
July 24th, 2010 at 11:24 PM
Hey amruth,
What you could do in that case is check the group name inside the login() method.
Here’s an example that might work:
Change this code in the login() method
$this->Redirect(array('controller' => 'Controller_name', 'action' => 'Action_name')); exit();to something like
// Use the user variable returned from the validate login function if ($user['Group']['name'] == 'admin') { $this->Redirect(array('controller' => 'ControllerName', 'action' => 'AdminActionName')); } else { $this->Redirect(array('controller' => 'SomeOtherControllerMaybe', 'action' => 'UserAction')); }Finally change the ‘find’ in validateLogin function in the model to
$user = $this->find(array('username' => $data['username'], 'password' => $data['password']), array('id', 'username', 'Group.name'));You would also want to make sure that a normal user can’t access an admin page by typing it in the url.
August 2nd, 2011 at 8:17 PM
Hi… I tried ur code. I got error like
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(); } } } Fatal error: Class 'AppController' not found in C:\xampp\htdocs\cake\app\controllers\users_controller.php on line 4I copied ur app_contoller.php program in /app/controllers/app_controller.php
Plz help me
August 4th, 2011 at 7:57 PM
Hello…
I tried ur code. But the login button is not working. IT doesnt show any error msg. I dont know where i did mistake.
Here is my code.
weee_users_controller.php
——————————
WeeeUser->recursive = 0; //$this->set('weeeUsers', $this->paginate());s $this->set('posts',$this->WeeeUser->find('all')); } function view($id = null) { if (!$id) { $this->Session->setFlash('Invalid weee user', true); $this->redirect(array('action' => 'index')); } $this->set('post', $this->WeeeUser->read(null, $id)); } function add() { if (!empty($this->data)) { if ($this->WeeeUser->save($this->data)) { $this->Session->setFlash('The weee user has been saved'); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash('The weee user could not be saved. Please, try again.'); } } } function edit($id = null) { if (empty($this->data)) { $this->data = $this->WeeeUser->read(null, $id); $this->Session->setFlash('The weee user could not be saved. Please, try again.'); }else { if($this->WeeeUser->save($this->data)) { $this->Session->setFlash('The weee user has been saved'); $this->redirect(array('action' => 'view',$id)); } } } function delete($id = null) { if (!$id) { $this->Session->setFlash('Invalid id for weee user'); $this->redirect(array('action'=>'index')); } if ($this->WeeeUser->delete($id)) { $this->Session->setFlash('Weee user deleted'); $this->redirect(array('action'=>'index')); } $this->Session->setFlash('Weee user was not deleted'); $this->redirect(array('action' => 'index')); } function ajax_login_form() { $this->layout = 'ajax'; if (!empty($this->data)) { if ($this->data['User']['username'] == '') $this->set('value', 0); else { $u = $this->User->findByUsername($this->data['User']['username']); if (empty($u)) $this->set('value', 1); else $this->set('value', 0); } } else $this->set('value', 0); } //Placeholder for login_form, required by CakePHP to see the login_form view //function login_form() { } function login_form() { //Check if they went here after submitting the form // Note that all our form data is preceded by the model name ['WeeeUser'] if(empty($this->data['WeeeUser']['username']) == false) { echo "im here"; //Here we validate the user by calling that method from the User model if(($user = $this->WeeeUser->validateLogin($this->data['WeeeUser'])) != false) { //Write some Session variables and redirect to our next page! $this->Session->setFlash('Thank you for logging in!'); $this->Session->write('WeeeUser', $user); // Go to our first destination! $this->Redirect(array('controller' => 'Weee_users', 'action' => 'index')); 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(); } function hello_world(){ } }—————————————————————————————–
weee_user.php
——————
array( 'username_must_not_be_blank'=>array('rule'=>'notEmpty','message'=>'This post is missing a username!'), 'username _must_be_unique'=>array('rule'=>'isUnique','message'=>'A post with this username already exists!') ), 'password'=>array( 'password_must_not_be_blank'=>array('rule'=>'notEmpty','message'=>'This post is missing its password!') ), 'email'=>array( 'email_must_not_be_blank'=>array('rule'=>'notEmpty','message'=>'This post is missing its email!'), 'email_must_be_unique'=>array('rule'=>'isUnique','message'=>'A post with this email already exists!') ) ); 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'])); if( empty($user) == false ) return $user; return false; } }———————————————————————————————————————————–
app_controller.php
———————-
Session->check('WeeeUser')) { $this->redirect(array('controller' =>'WeeeUsers', 'action' => 'login_form')); exit(); } } // Authenticate on every action, except the login form function afterFilter() { if( $this->action != 'login_form' ) $this->authenticate(); } */ // Check if they are logged in function authenticate() { // Check if the session variable User exists, redirect to loginform if not if(!$this->Session->check('WeeeUser')) { $this->redirect(array('controller' =>'WeeeUsers', 'action' => 'login_form')); exit(); } } // Authenticate on every action, except the login form function afterFilter() { if( $this->action != 'login_form' ) $this->authenticate(); } }——————————————————————————————————–
login_form.ctp
—————–
create('WeeeUser', array('action'=>'login_form') ); // Cake automatically knows, based on the input, to create input fields for these two. echo $form->input('username'); echo $form->input('password'); // Create the submit button echo $form->end('Login'); ?>——————————————————————————————————
August 4th, 2011 at 8:33 PM
Hello…
I tried ur code.
If i place my cursor in the login button, i cant able to see the URL in the below.
I checked my code. login_form.ctp is correct and it passes control to my users_controller.php.
if(empty($this->data['User']['username']) == false)
{}
else
{}
But this code is not working. Both if and else. I tested by giving echo message. I found its not entering in the loop. If i give echo message in the first line or last line in the program, it prints correctly.
Will u please help me to fix it?
function login_form()
{
//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->WeeeUser->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’ => ‘users’, ‘action’ => ‘index’));
exit();
}
else
{
$this->Session->setFlash(‘Incorrect username/password!’, true);
$this->Redirect(array(‘action’ => ‘login_form’));
exit();
}
}
August 4th, 2011 at 8:49 PM
Rose and Rehka,
I’m a bit rusty with my CakePHP, but it looks like your guys’ posted code handles user login inside the login_form function in the UsersController. Did you intend to put it in the login() function as the tutorial suggests? Also, what version of CakePHP do y’all use?
Recall that the login_form.ctp view will call our controllers login(..) function. Thus, the code should be inside your login(..) function instead of login_form(..).
Let me know if that helps.
August 4th, 2011 at 8:50 PM
Also, for long snippets of code, you can use the tags [ Sourcecode lang="php" ] and [ / Sourcecode ] (both without the spaces).
August 5th, 2011 at 8:38 PM
Now its working for me…. Thanks for your kind help…
October 13th, 2011 at 4:14 PM
hey if u want to make ur app_controller then it should be placed in app folder not under app/controller folder. all the controller will use ur app_controller functions. hope u understand it.