-
Book Overview & Buying
-
Table Of Contents
CakePHP 1.3 Application Development Cookbook
By :
Even though CakePHP provides a very powerful access control layer, sometimes we just need to implement user roles without having to go into the details of specifying which role is allowed access to which action.
This recipe shows how to limit access to certain actions by role-using routing prefixes, which constitutes a perfect solution for simple role-based authentication. In order to accomplish this recipe, we will assume the need to add three user roles in our application: administrators, managers, and users.
We should have a working authentication system, so follow the recipe, Setting up a basic authentication system. The users table should also contain a field to hold the user's role (named role.) Add this field with the following SQL statement:
ALTER TABLE `users` ADD COLUMN `role` VARCHAR(255) DEFAULT NULL AFTER `password`;
app/config/core.php file and look for the line that defines the Routing.prefixes setting. If it is commented out, uncomment it. Then change it to:Configure::write('Routing.prefixes', array('admin', 'manager'));
UsersController class definition:public function dashboard() {
$role = $this->Auth->user('role');
if (!empty($role)) {
$this->redirect(array($role => true, 'action' => 'dashboard'));
}
}
public function admin_dashboard() {
}
public function manager_dashboard() {
}
app/views/users/admin_dashboard.ctpapp/views/users/manager_dashboard.ctpapp/views/users/dashboard.ctpFor example, the contents for dashboard.ctp could simply be:
<h1>Dashboard (User)</h1>
app/controllers/app_controller.php file and change the components property declaration to include the following setting for the Auth component:public $components = array( 'Auth' => array( 'authorize' => 'controller', 'loginRedirect' => array( 'admin' => false, 'controller' => 'users', 'action' => 'dashboard' ) ), 'Session' );
AppController class, change the isAuthorized method and replace it entirely with the following:public function isAuthorized() {
$role = $this->Auth->user('role');
$neededRole = null;
$prefix = !empty($this->params['prefix']) ?
$this->params['prefix'] :
null;
if (
!empty($prefix) &&
in_array($prefix, Configure::read('Routing.prefixes'))
) {
$neededRole = $prefix;
}
return (
empty($neededRole) ||
strcasecmp($role, 'admin') == 0 ||
strcasecmp($role, $neededRole) == 0
);
}
default.ctp from your cake/libs/view/layouts folder to your application's app/views/layouts folder. While editing this layout, place the following code in the app/views/layouts/default.ctp layout file, right where you want the link to the dashboard to appear.<?php
$dashboardUrl = array('controller'=>'users', 'action'=>'dashboard');
if (!empty($user['role'])) {
$dashboardUrl[$user['role']] = true;
}
echo $this->Html->link('My Dashboard', $dashboardUrl);
?>
CakePHP will recognize prefixes defined in the Routing.prefixes setting as part of the URL, when they are preceding a normal route. For example, if admin is a defined prefix, the route /admin/articles/index will translate to the admin_index action in ArticlesController.
Since we are utilizing the controller authentication scheme in the Auth configuration, we know that every time a user is trying to access a non-public action, AppController::isAuthorized() is executed, and inside the method we set true if the user has access, or false otherwise.
Knowing that, we can check to see if a prefix is being used when a controller action is about to be executed. If the current route being accessed includes a prefix, we can match that prefix against the user's role to make sure they have access to the requested resource.
We are able to link to a role-only resource just by prefixing it with the appropriate prefix in the route. For example, to link to the manager's dashboard, the URL would be:
array( 'manager' => true, 'controller' => 'users', 'action' => 'dashboard' );
Change the font size
Change margin width
Change background colour