¿QUÉ ES ACL EN LA GESTIÓN DE USUARIOS EN UNA APLICACIÓN WEB?
ACL, Access Control Listo Lista de Control de Acceso, es una forma de control de permisos. En lugar de solo tener roles como Admin, Editor, Usuario, etc., ACL permite controlar accesos a nivel muy específico.
ACL Es un mecanismo de seguridad que permite definir qué usuarios o roles pueden realizar qué acciones sobre los recursos de tu aplicación.Componentes del ACL
- Recursos (Resources): Lo que se quiere proteger (proyectos, usuarios, archivos, facturas, etc.)
- Acciones (Permissions): Qué se puede hacer (leer, crear, actualizar, borrar, aprobar, etc.)
- Sujetos (Subjects): Quién quiere hacer la acción (usuario específico, rol, grupo)
- Reglas: Combinación de los tres anteriores.
Tipos de ACL más usados
Ventajas de usar ACL
- Mayor seguridad y control.
- Permisos muy granulares.
- Fácil auditoría de quién puede hacer qué.
- Flexible para crecer.
Desventajas de usar ACL
- Puede volverse complejo si no se diseña bien.
- Más trabajo de mantenimiento.
Alternativas
- Casbin (muy popular)
- AccessControl (librería JS)
- Permify
- Keycloak + RBAC
- Firebase Security Rules / Supabase RLS
Ejemplo de ACL con php
class ACL {
private $permissions = [];
public function __construct() {
// Definición de permisos por rol
$this->permissions = [
'admin' => [
'ver_proyectos' => true,
'crear_proyecto' => true,
'editar_proyecto' => true,
'eliminar_proyecto' => true,
'ver_reportes' => true,
],
'editor' => [
'ver_proyectos' => true,
'crear_proyecto' => true,
'editar_proyecto' => true,
'eliminar_proyecto' => false,
'ver_reportes' => false,
],
'usuario' => [
'ver_proyectos' => true,
'crear_proyecto' => false,
'editar_proyecto' => 'own', // Solo puede editar sus propios proyectos
'eliminar_proyecto' => false,
'ver_reportes' => false,
],
'invitado' => [
'ver_proyectos' => 'public', // Solo puede ver proyectos públicos
'crear_proyecto' => false,
'editar_proyecto' => false,
'eliminar_proyecto' => false,
'ver_reportes' => false,
]
];
}
/**
* Verifica si un rol tiene permiso para realizar una acción
*
* @param string $role Rol del usuario (admin, editor, usuario, etc.)
* @param string $action Acción a verificar (ver_proyectos, crear_proyecto, etc.)
* @param int|null $resourceOwnerId ID del dueño del recurso (para permisos 'own')
* @param int|null $userId ID del usuario actual
* @return bool
*/
public function tienePermiso($role, $action, $resourceOwnerId = null, $userId = null) {
// Si el rol no existe, denegar acceso por seguridad
if (!isset($this->permissions[$role])) {
return false;
}
$permission = $this->permissions[$role][$action] ?? false;
// Caso especial: Solo puede editar/ver sus propios recursos
if ($permission === 'own') {
return $resourceOwnerId == $userId;
}
// Caso especial: Solo puede ver recursos públicos
if ($permission === 'public') {
return true; // Aquí iría la lógica real según tu aplicación
}
// Permiso normal (true o false)
return (bool) $permission;
}
}
// ==================== EJEMPLO DE USO ====================
$acl = new ACL();
echo "Pruebas de Permisos";
$userId = 15; // ID del usuario actual
// Ejemplos más legibles
$userId = 15; // ID del usuario actual
echo "Admin puede crear proyecto? → " .
($acl->tienePermiso('admin', 'crear_proyecto') ? 'SI' : 'NO') . "
";
echo "Usuario puede editar su propio proyecto? → " .
($acl->tienePermiso('usuario', 'editar_proyecto', $userId, $userId) ? 'SI' : 'NO');
echo "Usuario puede editar proyecto de otro? → " .
($acl->tienePermiso('usuario', 'editar_proyecto', 25, $userId) ? 'SI' : 'NO');
echo "Editor puede eliminar proyecto? → " .
($acl->tienePermiso('editor', 'eliminar_proyecto') ? 'SI' : 'NO');
echo "Invitado puede ver proyectos? → " .
($acl->tienePermiso('invitado', 'ver_proyectos') ? 'SI (públicos)' : 'NO');