Using CakePHP's Auth Component

This article is over a year old and may contain outdated information.
This article pertains to CakePHP 1.2 only!

Since recently diving into CakePHP, I thought the best area to learn would be the user authentication and login. Luckily CakePHP comes bundled with an Authorization Component, and is literally the easiest thing to install. Below I will show you the basics of getting Auth working; do note that I was working in CakePHP 1.2 and PHP 5. To begin the following items must be implemented:

  • Database - A users table with the fields id, username and password (can be customized but recommended)
  • Controller - A users controller with a login and logout action
  • Model - A user model that correlates with the users table
Setting up AppController

The first thing we need to do is setup the AppController. We are placing the code in the AppController so that all child controllers inherit the AuthComponent. Begin by including the AuthComponent by binding it to the $components parameter. We will now create the beforeFilter() action that will hold all the Auth settings that will be passed to the child controllers.

<?php
class AppController extends Controller {
	public $components = array('Auth');
	public function beforeFilter() { 
		Security::setHash('md5');
		// Authenticate
		$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
		$this->Auth->loginRedirect = array('controller' => 'dashboard', 'action' => 'index');
		$this->Auth->loginError = 'No username and password was found with that combination.';
		$this->Auth->logoutRedirect = '/';
	}
} 
?>

In the beforeFilter() action above, you will notice 4 different variables being set. loginRedirect determines what controller/action pair to redirect to upon a successful login, where as logoutRedirect is the route to redirect to when logging out. loginAction is the controller/action in which your login form and processing will be taking place (its best to use CakePHPs defaults of /user/login/). For more information on these variables and additional variables, visit the corresponding cookbook page.

Setting up the UsersController

The next step is to create the UsersController and create the required actions. Within the login() action, there is no need to do any manual form processing or login, the auth system does that magically behind the scenes. You can literally leave this action empty, unless you wish to add a page title $this->pageTitle or validate it against the User model. Within the logout() action we run a redirect to the auth system, which logs us out and redirects to the logoutRedirect we specified in the AppController.

<?php
class UsersController extends AppController {
	public function login() {
		// No form processing needed, Auth does it automatically
	}
	public function logout() {
		$this->redirect($this->Auth->logout());
	}
	public function beforeFilter() {
		parent::beforeFilter();
		// Does not require being logged in
		$this->Auth->allow('signup', 'forgot');
		// If logged in, these pages require logout
		if ($this->Auth->user() && in_array($this->params['action'], array('signup', 'login'))) {
			$this->redirect('/');
		}
	}
}
?>

Now you may see some additional code; another beforeFilter()! This beforeFilter() is specific only to the current controller. It is extremely important to place parent::beforeFilter() in the action so that the parent beforeFilter() can initialize the AuthComponent. The allow() method takes arguments of actions (within the current controller) that do not require you to be logged in to view. Beneath that you will see some custom code that I have written. This code defines actions that require you to be logged out to view (it seems auth does not have anything for that). There are additional methods you can read about in the cookbook.

Creating the form

This is probably the easiest step of the process. Simply use Cake's built in HtmlHelper to build the form. Be sure to name the form after the model you are using for auth (e.g., User).

<?php 
echo $form->create('User', array('url' => array('controller' => 'users', 'action' => 'login')));
echo $form->input('username');
echo $form->input('password');
echo $form->submit('Login');
echo $form->end(); 
?>
Adding additional functionality

There are a couple ways to increase the functionality of the AuthComponent. Typically when you login, the user information in the database that matches the username/password combo is then stored in the AuthComponent. To retrieve the users information you would use the method $this->Auth->user(). A nice way of doing things is binding a $user variable to all views so you can access the users data.

// app_controller.php
public function beforeRender() {
    $this->set('user', $this->Auth->user());
    // In the views $user['User']['username'] would display the logged in users username
}
// controllers/users_controller.php
public function beforeRender() {
	parent::beforeRender();
}

If you would like to use a different model with the AuthComponent, you would add a $this->Auth->userModel variable in AppController::beforeFilter(). You can also add some additional conditions to the login query, for example, making sure a user is active.

$this->Auth->userModel = 'Member';
$this->Auth->userScope = array('User.status' => 'active');
Debugging problems

While working with the AuthComponent, I ran into one major problem. If you are using an old database that is ported over to use CakePHP and you did not use a password salt on the old passwords, be sure to disable Cake's salt (or leave it empty). I didn't realize this for nearly 2 days on why the passwords did not match and then it hit me, Cake's salted passwords will not match existing passwords. If this is a new database, no need to worry about the previous statements.

If for some reason you cannot have a field labeled username or password within your database, there are ways to set it to something else. You would do that by setting the $this->Auth->fields variables in AppController::beforeFilter(). For more information on this subject, visit the trouble shooting in the cookbook.

$this->Auth->fields = array('username' => 'email', 'password' => 'secretpass');
Conclusion

I hope this has been helpful to someone! I spent days debugging and installing this system and by doing so I learned the system in and out. If you have any questions be sure to leave a comment or drop a line by using the contact form. Thanks again for reading, come back for more tutorials!

13 Comments

  • This is very Help full Articles, for Fresher..
    I think this is better than CookBook.
    <b>Keep Posting Dude</b>
    <u>Thanks for your virtual help</u>
  • Hi when i am using authcomponent means when i include app_controller.php file m getting error table name not found in model but i am not using that table name in my code.what is the problem.
    please reply
  • where do i add the AppController? what is the file name and location? is this the app_controller.php file or part of users_controller.php?
  • hello,

    My name is jayu and I am new in cake php. I used cake 1.2.5 version whenever I try Auth component it is not working properly. Just copy, past your code just change $this->Auth->fields = array('username' => 'email', 'password' => 'password'); but its not redirect and $this->Auth->user() is always return false.
  • Very good and helpful information! However a little bit more information on password encryption would have been even great.

    Found this page after a few ones with incomplete information. Thanks again!
  • Hi Sophia here, I am a student of <a href="http://www.ccdastudy.com">ccda</a> Obtaining board simple search to find your site. I feel really nice to read especially in this article. It is very informative. All articles on your website are very informative and increase knowledge of many. However, this site plays a very important role in improving our new generation for the good work .... keep it up
    Sophia Atkinss
  • I'm using Cake 1.3. And the parent::beforeFilter simply does not work.
    for example I set the error message in the app_controller, but the default message still appears when I incorrectly login.

    David
  • I have attempted to follow your instructions in this article however when I add
    // app_controller.php
    function beforeRender() {
        $this->set('user', $this->Auth->user());
        // In the views $user['User']['username'] would display the logged in users username
    }
    
    then go to view a user I only see the current logged in user. I never get an error page if i change the username I am viewing to one that doesn't exist nor do I see a known user if try to view their profile.

    For instance if I log in as "testuser" I can see example.com/users/view/testuser but when i try to see "fred" at example.com/users/view/fred I get the content for example.com/users/view/testuser.

    It looks like $this->set('user', $this->Auth->user()); sets every user view to the logged in user so you will never see anything other than your own view.

    What am I doing wrong?
  • Hi, thanks for the article.

    How do you add username/password combinations into the users table? They can't be added manually because the password must be encrypted.
  • Great article.
    I would like to add that you can access Auth's information from the SessionHelper, so you don't have to use the $user var you're talking about, unless you'd rather use $user[stuff] than $session->read(stuff)
    Jimmy Bourassa ⋅
  • great, very clear, i was missing the "parent" call in the controllers so didn't work for me, i take a look of your code and now is working, thanks for the tip!!
  • great, very clear, i was missing the "parent" call in the controllers so didn't work for me, i take a look of your code and now is working, thanks for the tip!!
  • Thanks for your article, I've been looking for sites, searching a way to store/view the user data in layout after succesfully login action. I found the answer here.
    Jean Pierre Martínez