CakePHP 2.1
The example application in the CakePHP book does a very good job of covering setup and implementation of a basic Auth system.
Let’s continue building on that and cover a few other things, by adding a couple of more features and looking at some of the other things in more detail.
Good to say that cake started separating authentication and authorization as of 2.x release. While these concepts always go hand-in-hand, I feel it created a bit of confusion for beginners, because while separate in theory they were not clearly separate in implementation.
As always, your main players when it comes to Auth is AppController.php and User.php.
(Of course, UsersController.php is not to be forgotten about…)
Let’s go ahead and start with app/Controllers/AppController.php:
public $components = array('Auth', 'Session');
public function beforeFilter() {
$this->Auth->authorize = array('Controller');
$this->Auth->authenticate = array(
'all' => array (
'scope' => array('User.is_active' => 1)
),
'Form'
);
}
public function isAuthorized($user) {
if (($this->params['prefix'] === 'admin') && ($user['is_admin'] != 1)) {
return false;
}
return true;
}
}
First, as always we will include the necessary components. For the time being it’s just: public $components = array(‘Auth’, ‘Session’);.
Authorization is going to be controller-based. Meaning, we will tell CakePHP to authorize (let users access resources) based on the Controller actions.
(It’s nice that you can now specify such setting directly in the $components array, but I kept it in the beforeFilter() to show a slightly different approach).
Next, comes our Authentication setup. Unlike Authorization, which answers who is allowed to get to what, Authentication checks if the user is indeed who she claims to be (handle login/logout).
We’ll be using good ol’ login form, thus the ‘Form’ key in our setup.
Moving on, I’ve added a “scope” of User.is_active => 1… this presumes that in our users table we have a field called is_active and therefore only active users can access the application (everybody whose is_active status is equal to 0 is denied by default). More on this a little further.
isAuthorized() is a sweet little method, which helps us to fine-tune our permissions.
The implementation is truly up to your needs, but let’s see what we’ve got going on in this example…
if (($this->params['prefix'] === 'admin') && ($user['is_admin'] != 1)) {
return false;
}
return true;
}
The basic premise here is that an admin can access admin-related resources within the app. (We’ll get into prefix routing setup a little further down the line).
The presumption is that we have an is_admin field in our users table and if the user is not an admin $user[‘is_admin’] != 1 she cannot access any resource that has an “admin” prefix… again more on that a little later.
Otherwise, for all average Joe’s, we say return true; access whatever you want (once authorized) as long as it’s not an admin-related resource.
Alright then, let’s take a look at the prefix routing.
The setup couldn’t be simpler just un-comment the following in your app/Config/core.php.
Configure::write(‘Routing.prefixes’, array(‘admin’));
This concludes our basic setup. We’ll take a look at the User.php model as well UsersController.php in the next part, which is coming soon here.
p.s. For those who wish to play around with the setup, here’s all you’d need to get started with the users table.
[sql]
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`password` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`is_admin` tinyint(1) DEFAULT ‘0’,
`is_active` tinyint(1) DEFAULT ‘0’,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
[/sql]