Sistema de autenticación simple en CakePHP
Un método sencillo para implementar el manejo de permisos dentro de una aplicación hecha con CakePHP. Este método implementa un sistema de permisos en cascada con usuarios perteneciendo a un sólo grupo
CakePHP es un framework de PHP que tiene soporte para un sistema de permisos muy complejo en base a ACL. Sin embargo no todos los desarrollos web requieren de algo tan complejo. Para esos casos, con sólo usar el AuthComponent se puede manejar de manera sencilla. Esta es la manera en que lo he hecho yo:
Este método asume que cada usuario pertenece a un sólo grupo y pueden haber tantos grupos como se anecesario. Para lograrlo es necesario modificar el AppController para hacer que cargue el AuthComponent y un archivo en el que indicaremos los permisos.
Archivo de definición de permisos (permissions.php)
class AppPermissions extends Object {
// Define the groups allowed, order matters
var $groups = array("Public", "User", "Admin");
var $Users = array(
"index" => "User",
"view" => "Public",
"add" => "Admin",
"edit" => "Admin",
"delete"=> "Admin"
);
var $Posts = array(
"index" => "Public",
"view" => "Public",
"add" => "User",
"edit" => "User",
"delete"=> "User"
);
function __currentActionGroup($controller_name, $action) {
if (!isset($this->{$controller_name})) return false;
if (!isset($this->{$controller_name}[$action])) return false;
return $this->{$controller_name}[$action];
}
function groupHasAccess($controller, $action, $group = "Public") {
$group_index = array_search($group, $this->groups);
$allowedGroup = $this->__currentActionGroup($controller, $action);
$allowedGroup_index = array_search($allowedGroup, $this->groups);
return $group_index >= $allowedGroup_index;
}
}
?>
En este archivo, que debemos colocar en el directorio config de nuestra aplicación, definimos dos cosas:
- Los grupos permitidos en el sistema (en este caso User y Admin), el orden en que se definen los grupos es importante y determina una cascada de permisos (es decir, que como User tiene menor índice que Admin entonces Admin puede hacer todo lo que está permitido a los usuarios)
- Por cada controlador, las acciones y el grupo que puede ejecutar dicha acción.
Con este archivo ya definimos los permisos y si se agrega un nuevo controlador o una nueva acción será necesario incluirla en este archivo.
Carga de la definición de los permiso y filtrado
En el AppController se realiza todo el manejo de los permisos, de modo que los demás controladores queden libres de manejar esta lógica:
App::import("File", "permissions", true, CONFIGS);
class AppController extends Controller {
var $components = array("Auth");
var $permissions;
public function beforeFilter() {
$this->permissions = new AppPermissions();
$this->_initializeAuth();
}
function _initializeAuth() {
$this->Auth->authorize = "controller";
$this->Auth->loginAction = array(
"controller" => "users",
"action" => "login",
"plugin" => "",
"admin" => false
);
$this->Auth->loginError = __("Login or password incorrect", true);
if ($this->Auth->user() == null) {
$actionIsPublic = $this->permissions->groupHasAccess($this->name, $this->action);
if ($actionIsPublic) {
$this->Auth->allow();
} else {
$this->Session->setFlash(__("You must be logged in to access that action", true));
}
}
}
function isAuthorized() {
$group = $this->Auth->user("group");
$groupHasAccess = $this->permissions->groupHasAccess($this->name, $this->action, $group);
if (!$groupHasAccess) {
$this->Session->setFlash(__("You don\"t have access to that action", true));
}
return $groupHasAccess;
}
}
?>
Como se puede observar, lo primero que hace es cargar el archivo de permisos que creamos en la parte anterior. De modo que en la función beforeFilter (que CakePHP ejecuta automáticamente antes que cualquier otra parte del controlador) pueda ser instanciada la clase.
La función _initializeAuth configura algunas características del AuthComponent, entre ellas establece el método de autenticación en “controller” (para manejar los permisos por medio de la función isAuthorized del controlador). Es importante notar que esta función realiza parte del filtrado de permisos, debido a que en caso de que el usuario no esté autenticado (un visitante) la función isAuthorized no es ejecutada por el Auth Component.
Y por último, en isAuthorized se ejecuta el resto de la verificación de permisos que consiste en preguntar a la clase AppPermissions si el grupo al que pertenece el usuario actual está autorizado para acceder a la acción actual (en el controlador actual).
Como ven, la mayor parte de la acción se ejecuta en el AppController pero es la clase AppPermissions la que realiza la mágia de determinar quién tiene acceso a qué (por medio de la función groupHasAccess).
Recibe otros artículos como este automáticamente
Suscríbete vía RSS a aikon.com.ve ||
¿Qué es RSS?
Bueno pienso yo que aunque la forma que planteas de hacerlo es bueno, seria mucho mejor si se tuviera en cuenta la posibilidad de añadir nuevos gripos y permisos mas dinamicamente, Que el cliente no tenga que llamar al desarrollador para que cambie el archivo sino que lo pueda hacer solo. Aunque todavia no se como hacerlo y lo estoy necesitando, gracias por la informacion
febrero 13, 2009 // 11:26
El archivo de permisos (AppPermissions) lo podrias convertir en un modelo (Permission) y guardar esa misma info en una bd. No es dificil hacerlo flexible como tu deseas. Y la creacion y asignacion de permisos la puedes hacer con un controlador (PermissionsController). Si lo deseas puedo intentar publicar una entrada mas completa para explicar el concepto. Avisame
febrero 13, 2009 // 11:30
inclui los dos files que mencionas, ando viendo como funciona, soy nuevo en cake, me podrias explicar como esque funciona esto, es decir, yo tengo ya mi controller, model y view de users, tengo que hacer un login? o algo asi, gracias.
marzo 5, 2009 // 1:50
Para poner a funcionar el login tienes que crear una acción login vacía en el UserController (y la vista por supuesto). AuthComponent se encarga de hacer el login automáticamente.
marzo 5, 2009 // 22:58
Estaba pensando sobre el título de este post, creo que más que un sistema de autenticación es un sistema de autorización lo que tienes aquí. Buen trabajo, igualmente
marzo 18, 2009 // 10:49
Es verdad! La autenticación es automática con el AuthComponent… Bueh… xD
marzo 18, 2009 // 20:03
Buenas!
He estado probando tu código, pero me arroja el siguiente error :
“Undefined property: AppPermissions::$name”
El problema es la siguiente linea:
$allowedGroup = $this->__currentActionGroup($this->name, $this->action);
tienes idea de porqué puede ser?
septiembre 15, 2009 // 12:17
Creo que debería ser $allowedGroup = $this->__currentActionGroup($controller, $action);
Ya he actualizado el código. Avisa si funciona correctamente.
septiembre 15, 2009 // 12:24
Funcionó perfecto!
Muchas gracias
septiembre 15, 2009 // 13:10
Gracias a ti por reportar el error.
Saludos
septiembre 15, 2009 // 13:18
Otra cosa que no entendí de tu código es cuando pusiste lo siguiente:
if ($this->Auth->user() == null) {
$actionIsPublic = this->permissions->groupHasAccess ($this->name, $this->action);
no debería ser $this->Auth->user() != null?
septiembre 15, 2009 // 21:44
Está bien así, el tercer parámetro de groupHasAccess tiene un valor por defecto “Public” lo que hace ahí es que si no hay usuario en la sesión se le permita acceso al visitante si la acción es de púlica.
septiembre 16, 2009 // 0:22
UHHH … que error el mio xD
me había confundido en leer ….
ahora si … muchas gracias nuevamente
septiembre 16, 2009 // 12:41
muy bueno el post!!. soy de argentina y estuve leyendo mucho sobre esto sin encontrar lo que queria.. voy a probarlo ya!! espero me puedan dar una mano ya q soy nuevo en cake (aunke creo q ya un nuevo fan
)salu2!
noviembre 11, 2009 // 9:42
Hola, una pregunta, ¿Lo que has hecho no es equivalente a usar AclComponent?
Estoy creando una página web para una tienda virtual con PHP Cake y después de ver tu tutorial y ver el “oficial” de Cake [1] sobre AclComponent me he quedado con las dudas sobre qué me conviene más.
¿Como es que te decidiste a hacerlo de ésta manera?
[1] http://book.cakephp.org/view/641/Simple-Acl-controlled-Application
abril 3, 2010 // 12:32
consulta: donde defino a que grupo pertenece el usuario en la BBDD?? en un registro “user.group” o agrego una nueva tabla “group” referenciada desde “user.group_id”. ayuda!!
abril 10, 2010 // 12:29
hola que tal amigo, oye quiero hacerte una consulta, soy nuevo en cake, estoy en un poryecto de desarrollo donde tengo un control de usuarios, me interesa implementar la restriccion de acceso a usuarios dentro de mi portal, pero la duda es como identificar si el usuario sera administrador, publico o algun otro, tengo que agregar algun campo especial a mi base de datos, y como lo mandaria llamar en el controlador que mencionas, te agradezco de antemano tu apoyo.. Saludos
junio 7, 2010 // 11:19
El usuario tiene un campo group.
junio 7, 2010 // 14:55
hola he visto muchos post sobre control de usuario pero la pregunta es siempre utilizan users como tabla de usuarios y que tal si ya tengo una base de datos corriendo con el nombre de la tabla “usuarios” o “personal” lo que trato de decir es que no necesariamente lleve el nombre de la tabla users que contenga login y password, he tratado de modificar las palabras users por usuario pero me bota error he puesto lo que debe de ser en singular y en plurar he respetado los parametros pero bota error si serian tan amables y me explican gracias.
diciembre 6, 2010 // 12:51