Using CakePHP's Auth Component
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 actionModel- 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
I think this is better than CookBook.
<b>Keep Posting Dude</b>
<u>Thanks for your virtual help</u>
please reply
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.
Found this page after a few ones with incomplete information. Thanks again!
for example I set the error message in the app_controller, but the default message still appears when I incorrectly login.
David
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?
How do you add username/password combinations into the users table? They can't be added manually because the password must be encrypted.
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)