Uploader

An all around general purpose file uploader for CakePHP. Packaged as a stand alone plugin with file validation, file scanning and support for a wide range of basic mime types.

Using CakePHP's Auth Component

Friday, December 12th 2008, 1:20am
Topics: Tutorials, CakePHP
Tags: CakePHP, Auth, Component, Tutorial
Comments: 12
Permalink - Tinylink

Since recently diving into CakePHP, I thought the best area to learn would be a 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 {

	var $components = array('Auth');

	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 {

	function login() {
		// No form processing needed, Auth does it automatically
	}
	
	function logout() {
		$this->redirect($this->Auth->logout());
	}

	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
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
function beforeRender() {
	parent::beforeRender();
}


If you would like to use a different model with the Auth Component, you would add a $this->Auth->userModel variable in the AppController's 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 the 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!
Related Entries:

12 Comments

10 / 2 = ?
Allowed: [code] [b] [i] [u]
  • Jean Pierre Martínez
    Feb 6th 2009, 17:36
    1 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. :D
  • kener
    Feb 11th 2009, 13:30
    2 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!!
  • kener
    Feb 11th 2009, 13:39
    3 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!!
  • Jimmy Bourassa
    webiscake.com
    Mar 5th 2009, 07:46
    4 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)
  • qwant
    Apr 8th 2009, 10:21
    5 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.
  • Foroct
    Dec 11th 2009, 12:39
    6 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?
  • David
    Dec 28th 2009, 12:38
    7 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
  • Sophia Atkinss
    Mar 19th 2010, 03:15
    8 Hi Sophia here, I am a student of ccda 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
  • Arvind K.
    devarticles.in
    May 25th 2010, 23:58
    9 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!
  • jayu
    Jun 23rd 2010, 04:58
    10 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.
  • sherwin
    abbyandwin.net
    Sep 10th 2010, 09:31
    11 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?
  • zaiba
    Jan 18th, 22:06
    12 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