Welcome to the Cookbook

loading...

5.2 Authentication

User authentication systems are a common part of many web applications. In CakePHP there are several systems for authenticating users, each of which provides different options. At its core the authentication component will check to see if a user has an account with a site. If they do, the component will give access to that user to the complete site.

This component can be combined with the ACL (access control lists) component to create more complex levels of access within a site. The ACL Component, for example, could allow you to grant one user access to public site areas, while granting another user access to protected administrative portions of the site.

CakePHP's AuthComponent can be used to create such a system easily and quickly. Let's take a look at how you would build a very simple authentication system.

Like all components, you use it by adding 'Auth' to the list of components in your controller:

class FooController extends AppController {
    var $components = array('Auth');
  1. class FooController extends AppController {
  2. var $components = array('Auth');

Or add it to your AppController so all of your controllers will use it:

class AppController extends Controller {
    var $components = array('Auth');
  1. class AppController extends Controller {
  2. var $components = array('Auth');

Now, there are a few conventions to think about when using AuthComponent. By default, the AuthComponent expects you to have a table called 'users' with fields called 'username' and 'password' to be used.

In some situations, databases don't let you use 'password' as a column name. See Setting Auth Component Variables for an example how to change the default field names to work with your own environment.

Let's set up our users table using the following SQL:

CREATE TABLE users (
    id integer auto_increment,
    username char(50),
    password char(40),
    first_name varchar(32),
    last_name varchar(32),
    PRIMARY KEY (id)
);
  1. CREATE TABLE users (
  2. id integer auto_increment,
  3. username char(50),
  4. password char(40),
  5. first_name varchar(32),
  6. last_name varchar(32),
  7. PRIMARY KEY (id)
  8. );

Something to keep in mind when creating a table to store all your user authentication data is that the AuthComponent expects the password value stored in the database to be hashed instead of being stored in plaintext. Make sure that the field you will be using to store passwords is long enough to store the hash (40 characters for SHA1, for example).

If you want to add a user manually to the db - the simplest method to get the right data is to attempt to login and look at the sql log.

For the most basic setup, you'll only need to create two actions in your controller:

class UsersController extends AppController {

    var $name = 'Users';    
    var $components = array('Auth'); // Not necessary if declared in your app controller
 
    /**
     *  The AuthComponent provides the needed functionality
     *  for login, so you can leave this function blank.
     */
    function login() {
    }

    function logout() {
        $this->redirect($this->Auth->logout());
    }
}
  1. class UsersController extends AppController {
  2. var $name = 'Users';
  3. var $components = array('Auth'); // Not necessary if declared in your app controller
  4. /**
  5. * The AuthComponent provides the needed functionality
  6. * for login, so you can leave this function blank.
  7. */
  8. function login() {
  9. }
  10. function logout() {
  11. $this->redirect($this->Auth->logout());
  12. }
  13. }

While you can leave the login() function blank, you do need to create the login view template (saved in app/views/users/login.ctp). This is the only UsersController view template you need to create, however. The example below assumes you are already using the Form helper:

<?php
    echo $session->flash('auth');
    echo $form->create('User', array('action' => 'login'));
    echo $form->input('username');
    echo $form->input('password');
    echo $form->end('Login');
?>
  1. <?php
  2. echo $session->flash('auth');
  3. echo $form->create('User', array('action' => 'login'));
  4. echo $form->input('username');
  5. echo $form->input('password');
  6. echo $form->end('Login');
  7. ?>

This view creates a simple login form where you enter a username and password. Once you submit this form, the AuthComponent takes care of the rest for you. The session flash message will display any notices generated by the AuthComponent for example when the username and password combination do not match. Upon successful login the database record of the current logged in user is saved to session under the key Auth.User.

It is common that on successful login the user should be redirected to some place else, such as a dashboard. To achieve this Auth's loginRedirect property should be set to this location using either string or array URL notation. For example if your UsersController uses the Auth component, we can configure this property in a beforeFilter override method

class UsersController extends AppController {

    var $name = 'Users';    
    var $components = array('Auth'); 
 
    function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->loginRedirect = array('controller' => 'dashboard', 'action' => 'index');
    }

    function login() {
    }


    /** delegate /users/logout request to Auth->logout method */
    function logout() {
        $this->redirect($this->Auth->logout());
    }
}
  1. class UsersController extends AppController {
  2. var $name = 'Users';
  3. var $components = array('Auth');
  4. function beforeFilter() {
  5. parent::beforeFilter();
  6. $this->Auth->loginRedirect = array('controller' => 'dashboard', 'action' => 'index');
  7. }
  8. function login() {
  9. }
  10. /** delegate /users/logout request to Auth->logout method */
  11. function logout() {
  12. $this->redirect($this->Auth->logout());
  13. }
  14. }

Now, on success, we would arrive at our dashboard view. It is typical that you show a mast header on your page with the logged-in user's name and a logout link. To achieve this you can echo out a property of the Auth.User session variable.

<div id="mast">
    <?php echo $session->read('Auth.User.first_name'); ?>
    <?php echo $html->link('Logout', array('controller' => 'users', 'action' => 'logout')); ?>
</div>
  1. <div id="mast">
  2. <?php echo $session->read('Auth.User.first_name'); ?>
  3. <?php echo $html->link('Logout', array('controller' => 'users', 'action' => 'logout')); ?>
  4. </div>

That's how to implement an incredibly simple, database-driven authentication system using the Auth component. However, there is a lot more we can do. Let's take a look at some more advanced usage of the component in the subsequent sections.