Visión General
El sistema implementa un modelo de control de acceso basado en roles (RBAC - Role-Based Access Control) que permite gestionar qué acciones puede realizar cada usuario en el sistema.Modelos
Usuario (User)
Modelo:App\Models\User
Ubicación: app/Models/User.php
Tabla: users
Campos principales:
| Campo | Tipo | Descripción |
|---|---|---|
id | integer | Identificador único del usuario (PK) |
name | string | Nombre de usuario (login) |
email | string | Correo electrónico |
password | string | Contraseña hasheada (bcrypt) |
rol_id | integer | ID del rol asignado (FK) |
id_empresa | integer | ID de la empresa asignada (FK) |
num_doc | string | Número de documento de identidad |
nombres | string | Nombres completos |
apellidos | string | Apellidos completos |
telefono | string | Teléfono de contacto |
estado | string | Estado del usuario |
foto_perfil | string | Ruta de la foto de perfil |
Rol
Modelo:App\Models\Rol
Ubicación: app/Models/Rol.php
Tabla: roles
Campos principales:
| Campo | Tipo | Descripción |
|---|---|---|
rol_id | integer | Identificador único del rol (PK) |
nombre | string | Nombre del rol |
ver_precios | boolean | Permite ver precios de productos |
puede_eliminar | boolean | Permite eliminar registros |
Rol de Administrador
El sistema reserva elrol_id = 1 para el rol de Administrador, que tiene privilegios especiales:
Características Especiales
- Permisos ilimitados: Acceso automático a todos los módulos y acciones
- Bypass de verificaciones: No se evalúan permisos individuales
- Multi-empresa: Puede acceder y cambiar entre todas las empresas activas
- Sin restricciones: Todas las validaciones de permisos retornan
true
Implementación del Bypass
En el modelo User (app/Models/User.php:77-111):
app/Http/Middleware/CheckPermission.php:29-32):
app/Http/Controllers/Api/AuthController.php:53-56, 70-76):
Métodos de Verificación de Permisos
El modeloUser proporciona varios métodos para verificar permisos:
hasPermission($permissionName)
Verifica si el usuario tiene un permiso específico.boolean
hasAnyPermission(array $permissions)
Verifica si el usuario tiene al menos uno de los permisos especificados.boolean
hasAllPermissions(array $permissions)
Verifica si el usuario tiene todos los permisos especificados.boolean
getPermissions()
Obtiene todos los permisos del usuario.Collection de objetos Permission
Métodos del Modelo Rol
El modeloRol también implementa métodos similares:
hasPermission($permissionName)
hasAnyPermission(array $permissions)
hasAllPermissions(array $permissions)
Autenticación
Login
Endpoint:POST /api/auth/login
Parámetros:
- Busca el usuario por
emailoname - Verifica la contraseña con bcrypt (
Hash::check) - Crea sesión de Laravel (para exportaciones web)
- Genera token Sanctum (válido 8 horas)
- Carga empresas disponibles según rol
- Carga permisos del usuario
app/Http/Controllers/Api/AuthController.php:15-92
Logout
Endpoint:POST /api/auth/logout
Headers: Authorization: Bearer {token}
Proceso:
- Revoca el token actual de Sanctum
- Cierra la sesión de Laravel
- Invalida la sesión PHP
- Regenera el token CSRF
app/Http/Controllers/Api/AuthController.php:97-111
Obtener Usuario Actual
Endpoint:GET /api/auth/me
Headers: Authorization: Bearer {token}
Respuesta:
app/Http/Controllers/Api/AuthController.php:116-145
Refrescar Token
Endpoint:POST /api/auth/refresh
Headers: Authorization: Bearer {token}
Proceso:
- Revoca el token actual
- Genera un nuevo token con 8 horas de validez
app/Http/Controllers/Api/AuthController.php:150-164
Verificar Token
Endpoint:GET /api/auth/verify
Headers: Authorization: Bearer {token}
Respuesta:
app/Http/Controllers/Api/AuthController.php:209-222
Tokens de Autenticación
Laravel Sanctum
El sistema utiliza Laravel Sanctum para autenticación basada en tokens:- Generación:
$user->createToken('auth_token', ['*'], now()->addHours(8)) - Expiración: 8 horas desde la creación
- Almacenamiento cliente:
localStoragecon claveauth_token - Envío: Header
Authorization: Bearer {token}
Token en URLs (PDFs)
Para descargas de PDF desde el navegador, el sistema acepta tokens en query string: Ejemplo:/reporteNV/123?token={auth_token}
Middleware: TokenFromQuery (app/Http/Middleware/TokenFromQuery.php)
Funcionamiento:
- Extrae el token del parámetro
?token= - Lo convierte en header
Authorization: Bearer - Permite que Sanctum autentique la solicitud
Propiedades de Rol
ver_precios
Tipo:boolean
Propósito: Controla si los usuarios con este rol pueden ver precios de productos.
Uso típico:
true: Para vendedores, administradores, contadoresfalse: Para almaceneros que solo gestionan stock
puede_eliminar
Tipo:boolean
Propósito: Controla si los usuarios con este rol pueden eliminar registros.
Uso típico:
true: Para administradores y supervisoresfalse: Para usuarios operativos estándar
Mejores Prácticas
Crear Usuario
Verificar Permisos en Controladores
Verificar Permisos en Vistas (Blade)
Obtener Usuarios de una Empresa
Filtrar Usuarios por Rol
Consideraciones de Seguridad
Contraseñas
- Nunca almacene contraseñas en texto plano
- Use
Hash::make()para hashear contraseñas - Use
Hash::check()para verificar contraseñas - Laravel usa bcrypt automáticamente
Tokens
- Los tokens expiran en 8 horas
- Use
refreshpara renovar tokens cercanos a expiración - Revoque tokens al logout
- No comparta tokens entre usuarios
Validación de Rol
- Nunca confíe en
rol_iddel cliente - Siempre obtenga el usuario desde
$request->user() - Verifique permisos en el backend, no solo en frontend
Protección de Rutas
Troubleshooting
Usuario no puede acceder aunque tiene el permiso
- Verificar que el rol tiene el permiso asignado en
role_permission - Verificar que
rol_iddel usuario es correcto - Limpiar caché si existe
- Verificar que el permiso existe en la tabla
permissions
Admin no puede cambiar de empresa
- Verificar que
rol_id = 1 - Verificar que la empresa destino está activa (
estado = '1') - Verificar que
id_empresaexiste en la tablaempresas
Token inválido o expirado
- Verificar que el token se envía en el header correcto
- Verificar que el token no ha expirado (8 horas)
- Usar endpoint
/auth/refreshpara renovar - Si persiste, hacer logout y login nuevamente