Skip to main content

Descripción General

El sistema de roles y permisos permite controlar el acceso a funcionalidades mediante un modelo basado en resource.action. Cada usuario tiene un rol asignado, y cada rol tiene un conjunto de permisos configurables.

Modelo de Permisos

Estructura del Permiso

Los permisos siguen el patrón resource.action:
ventas.view       → Ver ventas
ventas.create     → Crear ventas
ventas.edit       → Editar ventas
ventas.delete     → Eliminar ventas

Tablas de Base de Datos

CREATE TABLE permissions (
  permission_id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,           -- Ej: "ventas.create"
  display_name VARCHAR(255),            -- Ej: "Crear Ventas"
  module VARCHAR(100),                  -- Ej: "ventas"
  action VARCHAR(50),                   -- Ej: "create"
  description TEXT,
  created_at TIMESTAMP,
  updated_at TIMESTAMP
);

Roles del Sistema

Rol Administrador (rol_id = 1)

El administrador tiene privilegios especiales:
  • Acceso total: Bypasea todas las verificaciones de permisos
  • Multi-empresa: Puede ver y cambiar entre todas las empresas activas
  • Sin restricciones: No requiere permisos explícitos en role_permission
app/Models/User.php:78
public function hasPermission($permissionName)
{
    // Admin (rol_id = 1) tiene todos los permisos
    if ($this->rol_id == 1) {
        return true;
    }
    
    return $this->rol && $this->rol->hasPermission($permissionName);
}

Roles Personalizados

Los roles no-admin tienen permisos configurables:
  • Vendedor
  • Cajero
  • Almacenero
  • Contador
Cada rol puede tener una combinación personalizada de permisos según las necesidades del negocio.

Verificación de Permisos

Middleware CheckPermission

El middleware CheckPermission protege las rutas API:
app/Http/Middleware/CheckPermission.php:17
public function handle(Request $request, Closure $next, string $permission): Response
{
    $user = $request->user();

    // Si no hay usuario autenticado, denegar acceso
    if (!$user) {
        return response()->json([
            'success' => false,
            'message' => 'No autenticado'
        ], 401);
    }

    // Admin (rol_id = 1) tiene acceso a todo
    if ($user->rol_id == 1) {
        return $next($request);
    }

    // Verificar si el usuario tiene el permiso
    if (!$user->hasPermission($permission)) {
        return response()->json([
            'success' => false,
            'message' => 'No tienes permiso para realizar esta acción'
        ], 403);
    }

    return $next($request);
}

Uso en Rutas

routes/api.php
// Proteger ruta con permiso específico
Route::get('ventas', [VentasController::class, 'index'])
    ->middleware('permission:ventas.view');

Route::post('ventas', [VentasController::class, 'store'])
    ->middleware('permission:ventas.create');

Route::delete('ventas/{id}', [VentasController::class, 'destroy'])
    ->middleware('permission:ventas.delete');

API de Permisos

Listar Todos los Permisos

module
string
Filtrar por módulo específico
curl -X GET "https://tu-dominio.com/api/permissions" \
  -H "Authorization: Bearer {token}"

Obtener Permisos del Usuario Autenticado

GET /api/permissions/user
curl -X GET "https://tu-dominio.com/api/permissions/user" \
  -H "Authorization: Bearer {token}"

Obtener Permisos de un Rol

GET /api/permissions/role/{rolId}
curl -X GET "https://tu-dominio.com/api/permissions/role/2" \
  -H "Authorization: Bearer {token}"

Actualizar Permisos de un Rol

PUT /api/permissions/role/{rolId}
permissions
array
required
Array de IDs de permisos a asignar
curl -X PUT "https://tu-dominio.com/api/permissions/role/2" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": [1, 2, 3, 5, 8, 12, 15]
  }'
Cuando se actualizan permisos de un rol, los usuarios con ese rol deben refrescar su token para que los cambios surtan efecto.

Refrescar Permisos del Usuario

Después de cambiar permisos, el frontend debe solicitar la recarga:
POST /api/permissions/refresh
curl -X POST "https://tu-dominio.com/api/permissions/refresh" \
  -H "Authorization: Bearer {token}"

Módulos de Permisos

Lista de módulos con permisos configurables:
MóduloPermisos DisponiblesDescripción
ventasview, create, edit, deleteFacturación y ventas
productosview, create, edit, deleteGestión de inventario
clientesview, create, edit, deleteBase de clientes
proveedoresview, create, edit, deleteGestión de proveedores
comprasview, create, edit, deleteRegistro de compras
cotizacionesview, create, edit, deleteCotizaciones
guias-remisionview, create, edit, deleteGuías de remisión
cuentas-cobrarview, editCuentas por cobrar
cuentas-pagarview, editCuentas por pagar
cajaview, create, edit, delete, abrir, autorizarGestión de cajas (ver Permisos de Caja)
bancoview, create, edit, deleteCuentas bancarias
finanzasview, create, edit, deleteReportes financieros
utilidadesviewDashboard de utilidades

Ejemplo de Implementación

1

Crear un rol

INSERT INTO roles (nombre, ver_precios, puede_eliminar) 
VALUES ('Vendedor', 1, 0);
2

Asignar permisos al rol

INSERT INTO role_permission (rol_id, permission_id) VALUES
(2, 1),  -- ventas.view
(2, 2),  -- ventas.create
(2, 5),  -- clientes.view
(2, 6);  -- clientes.create
3

Asignar rol al usuario

UPDATE users SET rol_id = 2 WHERE id = 5;
4

Verificar permisos en código

if ($user->hasPermission('ventas.create')) {
    // Usuario puede crear ventas
}

if ($user->hasAnyPermission(['ventas.edit', 'ventas.delete'])) {
    // Usuario puede editar O eliminar
}

if ($user->hasAllPermissions(['ventas.view', 'ventas.create'])) {
    // Usuario tiene AMBOS permisos
}

Propiedades Especiales de Roles

ver_precios

Controla si los usuarios con este rol pueden ver información de precios:
  • Precio de compra
  • Precio de venta
  • Márgenes de utilidad
  • Costos en reportes
if ($user->rol->ver_precios) {
    // Mostrar columnas de precios
}

puede_eliminar

Permite o restringe la eliminación de registros críticos:
  • Ventas emitidas
  • Compras contabilizadas
  • Documentos enviados a SUNAT
if ($user->rol->puede_eliminar) {
    // Mostrar botón eliminar
}
Estas propiedades son adicionales a los permisos granulares. Un usuario puede tener ventas.delete pero si puede_eliminar = false, no podrá eliminar registros.

Códigos de Error

CódigoMensajeCausa
401No autenticadoToken inválido o ausente
403No tienes permiso para realizar esta acciónUsuario no tiene el permiso requerido
404Rol no encontradoEl rol_id no existe
422Error de validaciónDatos inválidos en la solicitud
500Error al actualizar permisosError de base de datos

Mejores Prácticas

Principio de Mínimo Privilegio

Asigna solo los permisos estrictamente necesarios para cada rol.

Validación en Backend

NUNCA confíes solo en validación frontend. Siempre verifica permisos en el servidor.

Auditoría de Cambios

Registra quién cambia permisos de roles usando timestamps en role_permission.

Testing de Permisos

Prueba cada endpoint con diferentes roles para asegurar el control de acceso.

Build docs developers (and LLMs) love