Sistema de Autenticación y Permisos en Ragnos
Ragnos incorpora un sistema de autenticación ligero y flexible integrado directamente en el núcleo del framework. Este sistema gestiona sesiones de usuario, protección de controladores y control de acceso basado en roles (grupos).
El sistema se apoya principalmente en el servicio App\Services\Admin_aut y en la clase BaseController.
Tablas de Base de Datos
El sistema espera una estructura de base de datos específica:
gen_usuarios: Tabla de usuarios (usu_id,usu_nombre,usu_login,usu_pword,usu_activo,usu_grupo).gen_gruposdeusuarios: Tabla de roles (gru_id,gru_nombre).
Protección de Controladores
Todos los controladores que extienden de BaseController (incluyendo RDatasetController, RProcessController, etc.) tienen acceso a métodos de protección simplificados.
Flujo de Verificación
checkLogin()
Este método verifica si el usuario tiene una sesión activa. Si no la tiene:
- Para peticiones Web: Redirige al login (
admin/login). - Para API: Verifica el header
Authorizationcontra elusu_tokenen base de datos. Si falla, devuelve un error 401 JSON.
Uso: Se recomienda llamarlo al inicio de cualquier función que requiera autenticación, o en el constructor si todo el controlador es privado.
Controllers Públicos
Si tienes un controlador público (ej. página de inicio), simplemente no llames a checkLogin().
public function miFunciopPrivada()
{
$this->checkLogin();
// El resto del código solo se ejecuta si el usuario está logueado
return view('mi_vista');
}
checkUserInGroup($grupos)
Restringe el acceso exclusivamente a usuarios que pertenezcan a los grupos especificados.
- Parámetro: Puede ser un
stringcon el nombre de un grupo o unarrayde strings para permitir múltiples grupos. - Comportamiento:
- Si no cumple la condición, redirige a
admin/index(o devuelve 403/401 si es API). - Internamente llama a
checkLogin(), por lo que no es necesario llamar a ambos.
Uso:
public function __construct()
{
// Solo permitir acceso a Administradores
$this->checkUserInGroup('Administrador');
}
public function reporteGerencial()
{
// Permitir acceso a Administradores o Gerentes
$this->checkUserInGroup(['Administrador', 'Gerencia']);
// Lógica del reporte...
}
Servicio Admin_aut
Para lógica más granular dentro de tus vistas o controladores, puedes acceder directamente al servicio de autenticación.
Lo ideal es invocarlo mediante service('Admin_aut').
Funciones Principales
isLoggedIn()
Devuelve true si hay un usuario logueado, false en caso contrario.
id()
Devuelve el ID (usu_id) del usuario actual.
name()
Devuelve el nombre completo (usu_nombre) del usuario actual.
isUserInGroup($grupo)
Evalúa si el usuario actual pertenece al grupo indicado. Es muy útil para ocultar o mostrar botones en las vistas o aplicar lógica condicional. Comparación case-insensitive.
// En un controlador o vista
if (service('Admin_aut')->isUserInGroup('Ventas')) {
// Mostrar botón de crear pedido
}
campo($nombreCampo)
Obtiene cualquier campo de la tabla gen_usuarios para el usuario actual. La información se carga bajo demanda (lazy loading) la primera vez que se solicita un campo.
// Obtener el email o cualquier campo personalizado
$email = service('Admin_aut')->getField('usu_email');
Arquitectura de Drivers (RagnosAuthInterface)
A partir de Ragnos Framework v1.1+, el sistema de autenticación está desacoplado bajo el patrón Adapter/Driver. Esto permite intercambiar la capa de autenticación sin alterar la API pública documentada (service('Admin_aut'), $this->checkLogin(), $this->checkUserInGroup(), bitácoras de auditoría, etc.).
Drivers Disponibles
native(Por defecto):- Basado en sesiones nativas de PHP y las tablas
gen_usuariosygen_gruposdeusuarios. - Incluye soporte para Bearer Tokens en peticiones API contra
usu_token. - Comparación de roles insensible a mayúsculas/minúsculas.
shield:- Integración directa con CodeIgniter 4 Shield.
- Mapea llamadas a las APIs de Shield (
auth(),auth()->user(),auth('tokens'), etc.). - Si Shield no está instalado en el proyecto, el sistema realiza automáticamente un fallback seguro hacia el driver nativo.
Configuración del Driver
Puedes definir el driver activo en app/Config/RagnosConfig.php:
O sobreescribirlo por entorno en tu archivo .env:
Métodos del Contrato RagnosAuthInterface
Todos los drivers implementan App\ThirdParty\Ragnos\Auth\RagnosAuthInterface:
| Método | Tipo Retorno | Descripción |
|---|---|---|
checkLogin() |
bool |
Retorna true si hay un usuario autenticado. |
isUserInGroup(string $group) |
bool |
Comprueba pertenencia al grupo indicado. |
getUserId() |
?int |
Identificador único del usuario o null. |
getUserName() |
?string |
Nombre del usuario autenticado o null. |
getUserEmail() |
?string |
Correo electrónico del usuario o null. |
logout() |
void |
Cierra la sesión activa del usuario. |
checkApiToken(string $token) |
bool |
Valida un token Bearer para peticiones API. |
Para mantener 100% de retrocompatibilidad, los drivers y el servicio Admin_aut también exponen los métodos clásicos $auth->isLoggedIn(), $auth->id(), $auth->name(), $auth->getField($field) y $auth->checkUserInGroup($grupos).
Autenticación vía API
El sistema soporta autenticación para APIs REST de forma transparente.
- Al hacer login, se genera un token seguro en
usu_token. - El cliente debe enviar este token en el header
Authorization. checkLogin()detecta automáticamente si la petición es una llamada API (isApiCall()) y valida el token en lugar de la sesión de PHP.
Esto permite utilizar los mismos controladores para la interfaz web y para aplicaciones móviles o frontends desacoplados.
Ejemplo Completo
<?php
namespace App\Controllers;
use App\ThirdParty\Ragnos\Controllers\BaseController;
class Pedidos extends BaseController
{
public function __construct()
{
// Cargar helpers necesarios
helper(['form', 'url']);
}
public function index()
{
// 1. Asegurar que esté logueado
$this->checkLogin();
$auth = service('Admin_aut');
// 2. Obtener datos del usuario
$data['usuario'] = $auth->name();
$data['esAdmin'] = $auth->isUserInGroup('Administrador');
return view('pedidos/index', $data);
}
public function eliminar($id)
{
// 3. Restricción estricta: Solo Admins pueden eliminar
$this->checkUserInGroup('Administrador');
$model = new \App\Models\PedidosModel();
$model->delete($id);
return redirect()->to('/pedidos');
}
}