A Complete Login and Authentication Application Tutorial for CakePHP 2.3

in CakePHP/PHP/Tutorials & Samples/Web Development

Cake provides a very good tutorial on how to use the Auth component here, but its not complete. So, I spent a couple hours setting up a complete tutorial that you can download and check out a live demo. Here is what we will be creating: A web application that uses CakePHP’s Auth component to login and logout as well as bar access to certain pages if the user is not authorized. Once a user is logged-in, they will be able to go the dashboard and edit users. (Please note that I am not changing the default CakePHP theme. So below is what the login screen looks like:)

Edit: July 2014 Updates
Thanks to various reader inputs, I have updated the .zip file to fix some minor issues that were noticed. I also have a live demo that you can play with here. Fixes include:

  • fixed: deleted members can no longer login
  • fixed: error when you try to use an existing username or email again for a new user

login

Users Database Table

Let’s start by creating the users database table. The users table contains a user’s username, password and role. Additional fields are meta fields such as created and modified dates as well as a status field. (I never actually delete records, just turn their status to 0.) Here is what the final users table looks like:

CREATE TABLE users (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `username` VARCHAR(128),
    `password` VARCHAR(128),
    `email` VARCHAR(128),
    `role` VARCHAR(64),
    `created` DATETIME DEFAULT NULL,
    `modified` DATETIME DEFAULT NULL,
    `status` tinyint(1) NOT NULL DEFAULT '1'
);

Routes.php

Now, lets modify the core components of CakePHP to support our login module. First, we need to modify routes.php so that we can have a custom link for login, logout and the dashboard. This step is not required but I do it so that the URLs look clean..

	Router::connect('/dashboard', array('controller' => 'users', 'action' => 'index'));
	Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
	Router::connect('/logout', array('controller' => 'users', 'action' => 'logout'));

We also need to modify the home page so that it now points to our login action.

	Router::connect('/', array('controller' => 'users', 'action' => 'login'));

User.php

Next, we need to create a file called User.php in the app\Model folder. This is our users model where all of our validation logic will be. To accomplish this, I used some of Cake’s buil-in validation rules as well as my own custom validation rules. My rules are pretty simple: Usernames must be unique, non-empty, alphanumeric and be between 5 and 15 characters. Passwords must have a minimum length of 6 and must match the confirmation password. Emails must be unique and be at least 6 characters in length. Finally, roles must be in the list of accepted roles that I have selected, which include: ‘king’, ‘queen’, ‘bishop’, ‘rook’, ‘knight’ and ‘pawn’. Some of the custom validation functions I created include isUniqueUsername() to determine if a username is unique, isUniqueEmail() to determine if an email is unique, alphaNumericDashUnderscore() to only allow alphanumeric values, equaltofield() to check if a value is equal to another value. You can learn more about CakePHP’s custom validation rules here. Finally, I had to alter the beforeSave() function so that I hash the passwords that I get before saving them. For security reasons, you should never store unencrypted passwords in your Database. Below is the full code for User.php

App::uses('AuthComponent', 'Controller/Component');

class User extends AppModel {
	
	public $avatarUploadDir = 'img/avatars';
    
	public $validate = array(
        'username' => array(
            'nonEmpty' => array(
                'rule' => array('notEmpty'),
                'message' => 'A username is required',
				'allowEmpty' => false
            ),
			'between' => array( 
				'rule' => array('between', 5, 15), 
				'required' => true, 
				'message' => 'Usernames must be between 5 to 15 characters'
			),
			 'unique' => array(
				'rule'    => array('isUniqueUsername'),
				'message' => 'This username is already in use'
			),
			'alphaNumericDashUnderscore' => array(
				'rule'    => array('alphaNumericDashUnderscore'),
				'message' => 'Username can only be letters, numbers and underscores'
			),
        ),
        'password' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'A password is required'
            ),
			'min_length' => array(
				'rule' => array('minLength', '6'),  
				'message' => 'Password must have a mimimum of 6 characters'
			)
        ),
		
		'password_confirm' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'Please confirm your password'
            ),
			 'equaltofield' => array(
				'rule' => array('equaltofield','password'),
				'message' => 'Both passwords must match.'
			)
        ),
		
		'email' => array(
			'required' => array(
				'rule' => array('email', true),    
				'message' => 'Please provide a valid email address.'    
			),
			 'unique' => array(
				'rule'    => array('isUniqueEmail'),
				'message' => 'This email is already in use',
			),
			'between' => array( 
				'rule' => array('between', 6, 60), 
				'message' => 'Usernames must be between 6 to 60 characters'
			)
		),
        'role' => array(
            'valid' => array(
                'rule' => array('inList', array('king', 'queen', 'bishop', 'rook', 'knight', 'pawn')),
                'message' => 'Please enter a valid role',
                'allowEmpty' => false
            )
        ),
		
		
		'password_update' => array(
			'min_length' => array(
				'rule' => array('minLength', '6'),   
				'message' => 'Password must have a mimimum of 6 characters',
				'allowEmpty' => true,
				'required' => false
			)
        ),
		'password_confirm_update' => array(
			 'equaltofield' => array(
				'rule' => array('equaltofield','password_update'),
				'message' => 'Both passwords must match.',
				'required' => false,
			)
        )

		
    );
	
		/**
	 * Before isUniqueUsername
	 * @param array $options
	 * @return boolean
	 */
	function isUniqueUsername($check) {

		$username = $this->find(
			'first',
			array(
				'fields' => array(
					'User.id',
					'User.username'
				),
				'conditions' => array(
					'User.username' => $check['username']
				)
			)
		);

		if(!empty($username)){
			if($this->data[$this->alias]['id'] == $username['User']['id']){
				return true; 
			}else{
				return false; 
			}
		}else{
			return true; 
		}
    }

	/**
	 * Before isUniqueEmail
	 * @param array $options
	 * @return boolean
	 */
	function isUniqueEmail($check) {

		$email = $this->find(
			'first',
			array(
				'fields' => array(
					'User.id'
				),
				'conditions' => array(
					'User.email' => $check['email']
				)
			)
		);

		if(!empty($email)){
			if($this->data[$this->alias]['id'] == $email['User']['id']){
				return true; 
			}else{
				return false; 
			}
		}else{
			return true; 
		}
    }
	
	public function alphaNumericDashUnderscore($check) {
        // $data array is passed using the form field name as the key
        // have to extract the value to make the function generic
        $value = array_values($check);
        $value = $value[0];

        return preg_match('/^[a-zA-Z0-9_ \-]*$/', $value);
    }
	
	public function equaltofield($check,$otherfield) 
    { 
        //get name of field 
        $fname = ''; 
        foreach ($check as $key => $value){ 
            $fname = $key; 
            break; 
        } 
        return $this->data[$this->name][$otherfield] === $this->data[$this->name][$fname]; 
    } 

	/**
	 * Before Save
	 * @param array $options
	 * @return boolean
	 */
	 public function beforeSave($options = array()) {
		// hash our password
		if (isset($this->data[$this->alias]['password'])) {
			$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
		}
		
		// if we get a new password, hash it
		if (isset($this->data[$this->alias]['password_update']) && !empty($this->data[$this->alias]['password_update'])) {
			$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password_update']);
		}
	
		// fallback to our parent
		return parent::beforeSave($options);
	}

}

AppController.php

Next, AppController needs to be modified so that it uses Cake’s Auth component. This is where we tell the Auth component to redirect users to the index page after a successful login and to the login page after they logout. Once we do so, we need to update the beforeFilter() function to only allow the login action to be authorized in any controller. All other actions will only be accessible after the user is logged-in. I’ve also setup an isAuthorized() function that could be used to manage access to various pages. (The isAuthorized() function is not covered in this post, but its quite easy to setup one..)

	public $components = array(
		'DebugKit.Toolbar',
		'Session',
        'Auth' => array(
            'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
            'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
			'authError' => 'You must be logged in to view this page.',
			'loginError' => 'Invalid Username or Password entered, please try again.'
 
        ));
	
	// only allow the login controllers only
	public function beforeFilter() {
        $this->Auth->allow('login');
    }
	
	public function isAuthorized($user) {
		// Here is where we should verify the role and give access based on role
		
		return true;
	}

UsersController.php

At this point, we can create our Users controller by creating a file called UsersController.php in app/Controller. This controler contains functions for login, logout, edit, index, add, edit and delete. There is also a function called activate, which is used to turn a user’s status back to active after they have been deleted. (remember that I don’t actually delete users. I just change their status flag). One important thing to note is that I override the beforeFilter() function defined in AppController so that I now allow login() and add() functions to be visible without requiring authorization. If we don’t do this, we will never be able to add users to our application. The rest of the controller is pretty straightforward and the full code is presented below:


class UsersController extends AppController {

	public $paginate = array(
        'limit' => 25,
        'conditions' => array('status' => '1'),
    	'order' => array('User.username' => 'asc' ) 
    );
	
    public function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->allow('login','add'); 
    }
	


	public function login() {
		
		//if already logged-in, redirect
		if($this->Session->check('Auth.User')){
			$this->redirect(array('action' => 'index'));		
		}
		
		// if we get the post information, try to authenticate
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				$this->Session->setFlash(__('Welcome, '. $this->Auth->user('username')));
				$this->redirect($this->Auth->redirectUrl());
			} else {
				$this->Session->setFlash(__('Invalid username or password'));
			}
		} 
	}

	public function logout() {
		$this->redirect($this->Auth->logout());
	}

    public function index() {
		$this->paginate = array(
			'limit' => 6,
			'order' => array('User.username' => 'asc' )
		);
		$users = $this->paginate('User');
		$this->set(compact('users'));
    }


    public function add() {
        if ($this->request->is('post')) {
				
			$this->User->create();
			if ($this->User->save($this->request->data)) {
				$this->Session->setFlash(__('The user has been created'));
				$this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The user could not be created. Please, try again.'));
			}	
        }
    }

    public function edit($id = null) {

		    if (!$id) {
				$this->Session->setFlash('Please provide a user id');
				$this->redirect(array('action'=>'index'));
			}

			$user = $this->User->findById($id);
			if (!$user) {
				$this->Session->setFlash('Invalid User ID Provided');
				$this->redirect(array('action'=>'index'));
			}

			if ($this->request->is('post') || $this->request->is('put')) {
				$this->User->id = $id;
				if ($this->User->save($this->request->data)) {
					$this->Session->setFlash(__('The user has been updated'));
					$this->redirect(array('action' => 'edit', $id));
				}else{
					$this->Session->setFlash(__('Unable to update your user.'));
				}
			}

			if (!$this->request->data) {
				$this->request->data = $user;
			}
    }

    public function delete($id = null) {
		
		if (!$id) {
			$this->Session->setFlash('Please provide a user id');
			$this->redirect(array('action'=>'index'));
		}
		
        $this->User->id = $id;
        if (!$this->User->exists()) {
            $this->Session->setFlash('Invalid user id provided');
			$this->redirect(array('action'=>'index'));
        }
        if ($this->User->saveField('status', 0)) {
            $this->Session->setFlash(__('User deleted'));
            $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('User was not deleted'));
        $this->redirect(array('action' => 'index'));
    }
	
	public function activate($id = null) {
		
		if (!$id) {
			$this->Session->setFlash('Please provide a user id');
			$this->redirect(array('action'=>'index'));
		}
		
        $this->User->id = $id;
        if (!$this->User->exists()) {
            $this->Session->setFlash('Invalid user id provided');
			$this->redirect(array('action'=>'index'));
        }
        if ($this->User->saveField('status', 1)) {
            $this->Session->setFlash(__('User re-activated'));
            $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('User was not re-activated'));
        $this->redirect(array('action' => 'index'));
    }

}

All that remains is creating our ctp files that match the actions in our controller. Here they are:

login.ctp

This is the main page that is used to login to the system. It requires a valid username and password combination.

<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend><?php echo __('Please enter your username and password'); ?></legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password');
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>
<?php
 echo $this->Html->link( "Add A New User",   array('action'=>'add') ); 
?>

add.ctp

This is the page that allows you to add new users to the system. It is available when you are logged-in and when you are logged-out. The password is required twice, like in any professional website and validation rules, set in Users.php are enforced

<!-- app/View/Users/add.ctp -->
<div class="users form">

<?php echo $this->Form->create('User');?>
    <fieldset>
        <legend><?php echo __('Add User'); ?></legend>
        <?php echo $this->Form->input('username');
		echo $this->Form->input('email');
        echo $this->Form->input('password');
		echo $this->Form->input('password_confirm', array('label' => 'Confirm Password *', 'maxLength' => 255, 'title' => 'Confirm password', 'type'=>'password'));
        echo $this->Form->input('role', array(
            'options' => array( 'king' => 'King', 'queen' => 'Queen', 'rook' => 'Rook', 'bishop' => 'Bishop', 'knight' => 'Knight', 'pawn' => 'Pawn')
        ));
		
		echo $this->Form->submit('Add User', array('class' => 'form-submit',  'title' => 'Click here to add the user') ); 
?>
    </fieldset>
<?php echo $this->Form->end(); ?>
</div>
<?php 
if($this->Session->check('Auth.User')){
echo $this->Html->link( "Return to Dashboard",   array('action'=>'index') ); 
echo "<br>";
echo $this->Html->link( "Logout",   array('action'=>'logout') ); 
}else{
echo $this->Html->link( "Return to Login Screen",   array('action'=>'login') ); 
}
?>

which produces this form if the user is logged-in:

add-user-loggedin

and this form if the user is logged-out:

add-user-loggedout

index.ctp

Index.ctp acts as my dashboard and can only be accessed when a user is logged-in. This is where the list of users is displayed. It also uses Cake’s paginator to display the data.

<div class="users form">
<h1>Users</h1>
<table>
    <thead>
		<tr>
			<th><?php echo $this->Form->checkbox('all', array('name' => 'CheckAll',  'id' => 'CheckAll')); ?></th>
			<th><?php echo $this->Paginator->sort('username', 'Username');?>  </th>
			<th><?php echo $this->Paginator->sort('email', 'E-Mail');?></th>
			<th><?php echo $this->Paginator->sort('created', 'Created');?></th>
			<th><?php echo $this->Paginator->sort('modified','Last Update');?></th>
			<th><?php echo $this->Paginator->sort('role','Role');?></th>
			<th><?php echo $this->Paginator->sort('status','Status');?></th>
			<th>Actions</th>
		</tr>
	</thead>
	<tbody>						
		<?php $count=0; ?>
		<?php foreach($users as $user): ?>				
		<?php $count ++;?>
		<?php if($count % 2): echo '<tr>'; else: echo '<tr class="zebra">' ?>
		<?php endif; ?>
			<td><?php echo $this->Form->checkbox('User.id.'.$user['User']['id']); ?></td>
			<td><?php echo $this->Html->link( $user['User']['username']  ,   array('action'=>'edit', $user['User']['id']),array('escape' => false) );?></td>
			<td style="text-align: center;"><?php echo $user['User']['email']; ?></td>
			<td style="text-align: center;"><?php echo $this->Time->niceShort($user['User']['created']); ?></td>
			<td style="text-align: center;"><?php echo $this->Time->niceShort($user['User']['modified']); ?></td>
			<td style="text-align: center;"><?php echo $user['User']['role']; ?></td>
			<td style="text-align: center;"><?php echo $user['User']['status']; ?></td>
			<td >
			<?php echo $this->Html->link(    "Edit",   array('action'=>'edit', $user['User']['id']) ); ?> | 
			<?php
				if( $user['User']['status'] != 0){ 
					echo $this->Html->link(    "Delete", array('action'=>'delete', $user['User']['id']));}else{
					echo $this->Html->link(    "Re-Activate", array('action'=>'activate', $user['User']['id']));
					}
			?>
			</td>
		</tr>
		<?php endforeach; ?>
		<?php unset($user); ?>
	</tbody>
</table>
<?php echo $this->Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
<?php echo $this->Paginator->numbers(array(   'class' => 'numbers'     ));?>
<?php echo $this->Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
</div>				
<?php echo $this->Html->link( "Add A New User.",   array('action'=>'add'),array('escape' => false) ); ?>
<br/>
<?php 
echo $this->Html->link( "Logout",   array('action'=>'logout') ); 
?>

It produces this form:

dashboard

Edit.ctp

Edit allows you to edit data about a given user. In my case, I don’t allow users to change their username and their password only gets changed if they enter a value. (Most of these rules were inspired by the rules that WordPress has for users ) The code is below

<!-- app/View/Users/add.ctp -->
<div class="users form">
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend><?php echo __('Edit User'); ?></legend>
        <?php 
		echo $this->Form->hidden('id', array('value' => $this->data['User']['id']));
		echo $this->Form->input('username', array( 'readonly' => 'readonly', 'label' => 'Usernames cannot be changed!'));
		echo $this->Form->input('email');
        echo $this->Form->input('password_update', array( 'label' => 'New Password (leave empty if you do not want to change)', 'maxLength' => 255, 'type'=>'password','required' => 0));
		echo $this->Form->input('password_confirm_update', array('label' => 'Confirm New Password *', 'maxLength' => 255, 'title' => 'Confirm New password', 'type'=>'password','required' => 0));
		

		echo $this->Form->input('role', array(
            'options' => array( 'king' => 'King', 'queen' => 'Queen', 'rook' => 'Rook', 'bishop' => 'Bishop', 'knight' => 'Knight', 'pawn' => 'Pawn')
        ));
		echo $this->Form->submit('Edit User', array('class' => 'form-submit',  'title' => 'Click here to add the user') ); 
?>
    </fieldset>
<?php echo $this->Form->end(); ?>
</div>
<?php 
echo $this->Html->link( "Return to Dashboard",   array('action'=>'index') ); 
?>
<br/>
<?php 
echo $this->Html->link( "Logout",   array('action'=>'logout') ); 
?>

Here is a screenshot:

edit-user

Download it all

That concludes the tutorial. You can download the entire tutorial in zip format here.

Tags:

Mifty Yusuf is a Montreal-based software developer who enjoys playing with new web technologies as well as comic books and illustrations. He beleives that, no matter what the question is, the answer is always Batman!

233 Comments

  1. hi mifty.. great tutorial.. i got a problem when i tried to delete myself as user and then i still can login the deleted user

    • HI Nabila,
      That is correct. This tutorial does not handle the case of deleted users being locked out. What you need to do is modify the login function to also check the user status so that you only allow users that have a status of active to login. It’s a simple update to the query that should no more than 1 minute to do.

  2. Hello mifty,

    i must say that this tutorial is awesome! everything works great! after completed the tutorial, i tried to insert row number to table view. instead of displaying the id from database, i want to display a row number for each of the row but it seem like after i go to next page, it will start with number 1 again. hope you can give any idea ๐Ÿ™‚ thanks ๐Ÿ™‚

      • Hey, thanks for reply ๐Ÿ™‚

        yes. just an ordered numbers. Here i share the codes but when click to next page, the number start at 1 again not continue from previous page.

  3. MIFTY !! SIR i tried to do as it is as described in ur post above but after running on local host i got teh following errors :- I shall be literally thankful if you will help !!!

    Home ContactUsers
    Missing Plugin
    Error: The application is trying to load a file from the DebugKit plugin

    Error: Make sure your plugin DebugKit is in the app\Plugin directory and was loaded

    load(string, array)
    CORE\Cake\Controller\Controller.php line 643 โ†’ ComponentCollection->init(UsersController)
    CORE\Cake\Routing\Dispatcher.php line 186 โ†’ Controller->constructClasses()
    CORE\Cake\Routing\Dispatcher.php line 165 โ†’ Dispatcher->_invoke(UsersController, CakeRequest)
    APP\webroot\index.php line 108 โ†’ Dispatcher->dispatch(CakeRequest, CakeResponse)

    • Hi, it appears that you are trying to load the debugkit but it can’t be found or it was not loaded in your config files. If you don’t need the plugin, then comment it out in the base controller since this where it is loaded. If you do need the plugin, make sure that it is in the right folder and that it is loaded. That should fix your problem

  4. Hello Mifty, Thank you for this awesome post. It has really helped me a lot as i am completely new to CakePHP. ……. ๐Ÿ™‚

    Everything is working perfectly But i have one problem that when i click the logout button, then it is redirecting to a page as mentioned in my code successfully, But when i click BACK button on browser, then it is showing me that page where i have displayed all data. I mean Logout is not stopping users from going Back and showing all webpages without any security. What should i do mifty.? How should i stop users from seeing those webpages again??

    • Hi,
      The issue that you are experiencing has nothing to do with cakephp. This is a browser caching issue. I’m afraid that there is not much that you can do about the back button being pressed.
      In fact, you should have the same problem if you logout of pulse sites like gmail or Facebook.

  5. Thanks Mifty.

    It works for me very well in the local development environment.
    I’m yet to make changes as per my requirement and put it into production.

    Yours is one of the beautiful and elegant tutorial for a cakephp beginner like me.
    I have bookmarked your page and I will keep coming for more. ๐Ÿ™‚

    Request you to offer more. We want more. ๐Ÿ™‚

    Sincere thanks again for helping me.

    Merry Christmas and Happy new year.

    Love
    Satheesh

  6. hey i’ll never forget this blog and http://miftyisbored.com/ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ GREAT TUTORIAL!!!
    THANKS BE TO GOD!!!

    when my site STARRED, ill remember this blog and http://miftyisbored.com/… hey man you make my day…
    this is one of my biggest dream, to have a login sign up sessions :D:D :D: D ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€
    God bless you Mifty ๐Ÿ˜€

  7. Hi,

    I am really confused about $this->data[$this->alias]. what is this all about. also kindly let me know that in equaltofield function why have you used “$this->data[$this->name][$otherfield] === $this->data[$this->name][$fname]”, why are we not comparing directly the $check array value to $otherfield value?

  8. Hi, I have a question, Why when I attemp log in with my Form.. I put my Form like your form the view login.ctp
    But I have error in php echo $this->Form->create(‘User’); that’s why my error is: Cannot redeclare class UserModel .

    • Hi Angela,
      Based on the error that you are gettting, it would appea that you have declared the model User twice. Its not an issue in your view but rather an issue in your model. Make sure that you only have one declaration of User in your application.

  9. Hi Mifty,

    Thank you for the nice tutorial on authentication. It really helped me. I found a problem while I was working on it. It is about the user delete and activation action. I think the code should be something like this:

    Form->postLink(__(‘Delete’), array(‘action’ => ‘delete’, $user[‘User’][‘id’]), array(), __(‘Are you sure you want to delete # %s?’, $user[‘User’][‘id’]));
    } elseif ($user[‘User’][‘status’] != 1) {
    echo $this->Form->postLink(__(‘Activate’), array(‘action’ => ‘activate’, $user[‘User’][‘id’]), array(), __(‘Are you sure you want to re activate # %s?’, $user[‘User’][‘id’]));
    }
    ?>

    What do you think ?

    Thanks again.

    • In my previous post I missed some code. Here it is:

      if ($user[‘User’][‘status’] != 0) {
      echo $this->Form->postLink(__(‘Delete’), array(‘action’ => ‘delete’, $user[‘User’][‘id’]), array(), __(‘Are you sure you want to delete # %s?’, $user[‘User’][‘id’]));
      } elseif ($user[‘User’][‘status’] != 1) {
      echo $this->Form->postLink(__(‘Activate’), array(‘action’ => ‘activate’, $user[‘User’][‘id’]), array(), __(‘Are you sure you want to re activate # %s?’, $user[‘User’][‘id’]));
      }

  10. Thank you thank you thank you!
    I was being driven mad. I had tried 6 different versions of logon apps, both with and without password hashing, and none of them worked. I hoped that this one would be my savior: the online version works a treat. I copied the app directory over a fresh version of cakephp and just changed the database.php to match my MySQL database (password and database name only).
    I created a new user and BINGO! no more ‘the username or password is invalid!
    All I have to do now is to figure out why all the other versions failed…

  11. Please help me with this error I am getting:

    Missing Database Table

    Error: Table social_profiles for model SocialProfile was not found in datasource default.

    • Resolved: In routes.php, I had to put the custom routes ABOVE
      require CAKE . ‘Config’ . DS . ‘routes.php’;

  12. hello,
    look I need your help with this, Reproduce all your steps to create a login that redirects me from the homepage , and everything works me less when trying to enter , I have as user ‘ admin1234 ‘ and the password the same ‘ admin1234 ‘ ‘m using wamp , I necesecito this urgent please help …
    thx.

  13. Hi Miffy!

    I was amazed on this! but im having a lil bit trouble because i wanna do to the user is once i deleted his acct. he will not able to sign in again or else he will create a new account.. but in this case when i click on delete my account i can still log in..
    i hope you can help me on this. ๐Ÿ™‚ thanks!

    • Hi Roselyn,
      The reason why this is happening is because the tutorial does not currently handle the case of deleted users during login. You just have to modify the query in the login action to add one additional condition

       deleted &lt;&gt; 0

      This basically tells us to only let active users login and all deleted users get rejected.

  14. Hie
    My query is.. If i want to use different table Like Guests then how can we configure with auth,
    I think ,there need some changes for any custom table with auth component .

    Thanks

    • You can simply implement the

      public $components = array(
      ‘Auth’ => array(
      ‘authenticate’ => array(
      ‘Form’ => array(
      ‘fields’ => array(‘username’ => ’email’),
      ‘userModel’ => ‘Member’
      )
      )
      )
      );

      Here member is other model name.

  15. I just started with Cake and your tutorial is literally the first piece of code I ever did with that framework. Great tutorial most of it works out of the box.

    However, I found that beforeSave() is simply not invoked. The CakeEventManager dispatches explicitly for AppModel.beforeSave(), no mention of User.beforeSave(). Didn’t track it, but it seems that the same happens for validation, too. Any idea what I may be doing wrong?

    • Okay, found the issue. The so called strength of such frameworks is also the greatest weakness, when it comes to safe and secure code. My “User.php” was called “Users.php”, which made the application perfectly running, but ignoring the model code. Writing security critical code will be a challenge, if the framework does not bark on obvious programmer errors.

      Once again, thanks for this great skeleton code.

  16. Hiii Mifty ,
    his wonderful tutorial. am new in cake php and am just dowbload your code and run on localhosr that an geting this error

    Warning: include(Cake\bootstrap.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Cake\app\webroot\index.php on line 93

    Warning: include(): Failed opening ‘Cake\bootstrap.php’ for inclusion (include_path=’C:\xampp\htdocs\Cake\lib;.;C:\xampp\php\PEAR’) in C:\xampp\htdocs\Cake\app\webroot\index.php on line 93

    Fatal error: CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your \cake core directory and your \vendors root directory. in C:\xampp\htdocs\Cake\app\webroot\index.php on line 102

    So ,How can i solved it plz help me .

    thanks

  17. Hi, great tutorial, really helped me with a small project that needed admin routing.

    was just wondering what’s the reason you do not use the built-in validation for unique fields ?
    (isUnique model validation )

    • Hi Willem,
      great question! I was recently asked this same question by a developer from a fortune 500 company. the simple answer is laziness. When I first started using CakePHP, I was not aware of this validation so I wrote my own and I’ve been using it ever since. Good coding practice says that you should reuse as much as possible… So, I really need to stop using my own custom version of this function.

  18. Hi,
    The tutorial is amazing. I really liked it. I implemented the same with ACL in my cake application. I have a new requirement with two different logins. One for customer and the other for the staff. I am really confused right now on how to implement the feature because I cant use roles here . both the staff and the customer have two separate forms .

    • I would suggest using the same model for both types of users and just have a field called type inside the users table. Then you could create two separate views: one called staff_login and one called customer_login. Then for each one of these views, you can pre-fill the type to either customer or staff. This way, you keep one central logic and just use the type field to determine what type of user you are dealing with.

Leave a Reply

Your email address will not be published.

*

Latest from CakePHP

Go to Top