The most basic aspect of many web apps is user authentication and CakePHP, a PHP framework, provides some pretty impressive capabilities in that arena. Unfortunately for those new to the framework, the documentation isn’t the clearest and other tutorials on the web regarding this subject aren’t written with much clarity either. So here’s my attempt to help newbies such as myself get their heads wrapped around some basic user authentication. And when I say basic, I mean really basic. This step-by-step guide should help you get a simple user authentication system up and running.
1. Installing CakePHP
I recommend starting this with a fresh install of CakePHP. (As of this writing, the latest stable version is 1.2.4.8284.) I have it set up on a development server so I simply uploaded the scripts into a subdirectory… www.domain.com/your_cake_dir/ The directory structure should be as follows:
domain.com - your_cake_dir -- app -- cake -- vendors -- .htaccess -- index.php - mydir - yourdir
Make sure everything else is in order before going on, too. I’m referring to basic housekeeping stuff like ensuring your /app/tmp directory and its subdirectories are writable by the webserver as well as making sure Cake can connect to your database. That is done inside /app/config/core.php.
2. Creating the ‘users’ database table
The Auth component expects a table named users with fields named username and password. Auth can be configured to look for different fields and I will cover that… later. Here is the SQL I used to create the table in MySQL:
CREATE TABLE IF NOT EXISTS `users` ( -- Cake needs the 'id' field `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, -- 'username' and 'password' fields for Auth to function properly `username` varchar(255) NOT NULL UNIQUE, `password` varchar(40) NOT NULL, -- 40 for SHA-1, 32 for MD5 -- optional field Cake uses `created` DATETIME );
Auth will be automatically hashing passwords for us so ensure that the password field is long enough to hold it. CakePHP uses the SHA-1 algorithm by default which results in a string of forty (40) characters. Yes, it is possible to change the algorithm Cake uses and, like changing the field names Auth looks for, I’ll cover that at the end of this article.
At this point all we have is a fresh install of Cake and a single table in a database. Nothing more.
3. Bake yourself a skeleton
You can either bake or scaffold yourself a skeleton app. I chose to bake as it goes a bit further than a simple scaffold. To bake, login to a command prompt, run the code below and follow the prompts. This will create the basic model, view and controller for your user datasource. We’ll be adding on to this foundation to get our user authentication working.
cake bake all
The script is located at /cake/console/cake. Depending on your environment, you may need to change the permissions to allow yourself to execute it. That or, on a Unix server, su/sudo. Your choice. Once the script is done, you should now have a file /app/controllers/users_controller.php. To that file we will be adding the configuration for Auth as well as the login() and logout() actions that Auth requires.
4. /app/controllers/users_controller.php
Here are the entire contents of my users_controller.php file with some things commented away for brevity’s sake. I have added the entire beforeFilter() action as well as the login() and logout() actions.
<?php class UsersController extends AppController { var $name = 'Users'; var $helpers = array('Html', 'Form'); var $components = array('Auth'); function beforeFilter() { //Configure AuthComponent //These are just some of the basic configuration options. Many more are //available and documented at http://book.cakephp.org/view/247/ and //http://book.cakephp.org/view/248/ //tell Auth what controller/action pair it needs to use to present the login form //We'll still need to create this view at /app/views/users/login.ctp $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login'); //tell the Auth component where the user should be redirected after a successful authentication $this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'index'); //tell the Auth component where the user should be redirected after a successful logout $this->Auth->logoutRedirect = '/users'; //error message you want displayed if authentication fails. $this->Auth->loginError = 'Invalid credentials. Try again.'; //tell Auth what actions are allowed without any authentication $this->Auth->allow('index','view'); } function index() { //as baked, no changes here } function view($id = null) { //as baked, no changes here } function add() { //as baked, no changes here } function edit($id = null) { //as baked, no changes here } function delete($id = null) { //as baked, no changes here } function login() { //You must add this function, but you can leave //it empty. Auth provides all of the functionality. } function logout() { //set the flash so user has some feedback upon logout $this->Session->setFlash('You have been logged out.'); //redirect to Auth for the work to be done $this->redirect($this->Auth->logout()); } } ?>
The comments should make it clear what each important line does. Again, the only bits I added were the beforeFilter(), login() and logout() actions.
5. Creating the login view
All we’re doing here is telling Cake how to display the login form to the user. At my current level of Cake experience, I went with a very simple example and will be leaving it at that for now. Form comes after function in my books, especially in web development. Anyway… /app/views/users/login.cpt:
<?php $session->flash('auth'); echo $form->create('User', array('action' => 'login')); echo $form->inputs(array( 'legend' => __('Login', true), 'username', 'password' )); echo $form->end('Login'); ?>
I don’t know much about Cake’s form helper nor do I know the first thing about how Cake handles sessions. So, as you can see, this file is entirely uncommented. This code comes direct from the Cake Cookbook’s tutorial on ACLs, Cake’s far-more-advanced user management system.
6. Testing the system
With these few components in place, we’re almost ready to give Auth a test run. First we must get a record into our users table so Auth can have something to authenticate against. You’ll need to enter the data manually via your SQL prompt or some other tool. Since I’m using MySQL, I used phpMyAdmin to do this. Be sure to insert the hash of your password into the password field and not the password itself. Hash generator. There is another option and I’ll discuss that briefly here in a minute. On to a quick test.
Point your browser to www.domain.com/your_cake_dir/users and you should be presented with a table showing you your single entry in the users table. To the right you should see the View, Edit and Delete links. Below the table you’ll see the New User link. At this point we have not authenticated. Click on the View link and you should be presented with the information for the user you’ve already added. Since we had the view action added to the list of actions that didn’t require authentication for the users controller, this is exactly what we would expect. (If we had included the add action to this list, we could have added the first record to the table right here.)
Now click the Edit User link. You should be presented with a form asking you for a username and password. Once logged in you should have authority to delete, edit and add users at will. And with that you have a simple user management system up and running. To logout you just need to go to www.domain.com/your_cake_dir/users/logout.
Customization, other considerations
As mentioned earlier, it is possible to modify Auth’s behavior. The two things I hinted at above were changing the fields Auth looks for from ‘username’ and ‘password’ to something of your own choosing. The second was changing Auth’s default hashing algorithm. Both of these are configurable in the beforeFilter() function of the users controller as seen here:
$this->Auth->fields = array('username' => 'email', 'password' => 'passwd'); Security::setHash('md5'); //or sha1 or sha256.
The modifications we made to the users controller can also be made to /app/app_controller.php resulting in the same restrictions being implemented across the entire application and not just on the users controller. If you don’t have that file at this point (and per this tutorial you don’t), you can just create it like so:
<?php class AppController extends Controller { var $components = array('Acl', 'Auth'); function beforeFilter() { //same stuff in here as in users_controller.php } } ?>
The login() and logout() actions would remain in the users controller.
Shazzam
And that is that. CakePHP offers some pretty flexible and powerful tools for building sound web applications quickly… and if not quickly, at least much faster than starting from absolute scratch. We constructed a minimal example here as a demonstration, but Cake is also capable of handling complex user management requirements via its aforementioned ACLs. Hopefully this little tutorial here (my first) helps you guys better understand CakePHP’s Auth component and can serve as motivation to continue exploring this framework.



Comments
Dean 25 Nov 2009 at 08:36
Nice post. Thanks for the easy tutorial.
Comments are moderated.