Verificar Permisos

Como funciona la verificacion de permisos internamente

verificarpermisoscheckvalidarautorizacion

Verificar Permisos

Como el sistema verifica si un usuario puede realizar una accion.

Flujo de Verificacion

Request → Respuesta

Usuario hace request (ej: POST /api/events)

  1. AUTENTICACION - ¿Usuario logueado?

    • NO → 401 Unauthorized
    • SI → Continua
  2. OBTENER PERMISOS - Buscar en cache (Redis)

    • Cache hit → Usa cache
    • Cache miss → Busca en DB
  3. VERIFICAR PERMISO - ¿Tiene "events.manage"?

    • NO → 403 Forbidden
    • SI → Continua
  4. EJECUTAR ACCION - Procesa el request y retorna resultado

Algoritmo de Verificacion

Pseudocodigo

function hasPermission(userId, permissionKey):
    // 1. Admins tienen todo
    if user.role === "admin":
        return true

    // 2. Buscar ACL Object
    object = findAclObject(permissionKey)
    if not object:
        return false

    // 3. Verificar rol permitido
    if user.role not in object.allowedRoles:
        return false

    // 4. Buscar permiso asignado
    permission = findAclPermission(userId, object.id)
    if not permission:
        return false

    // 5. Retornar valor de allowed
    return permission.allowed

Casos Especiales

ADMIN:

  • Siempre retorna true
  • No necesita buscar en DB

ROL NO PERMITIDO:

  • Si el rol del usuario no esta en allowedRoles
  • Retorna false sin buscar permission

SIN PERMISO ASIGNADO:

  • Si no existe registro en acl_permission
  • Retorna false (deny by default)

PERMISO EXPLICITAMENTE DENEGADO:

  • Si existe permission pero allowed = false
  • Retorna false

Cache de Permisos

Como Funciona

El sistema cachea permisos en Redis:

  1. Primera consulta: Busca en DB, guarda en Redis
  2. Siguientes consultas: Lee de Redis (rapido)
  3. Al modificar permiso: Invalida cache
  4. TTL expira (5 min): Proxima consulta recarga de DB

Estructura del Cache

Key: acl:permissions:{userId}

Valor (JSON):

{
  "process.read": true,
  "process.manage": true,
  "events.read": true,
  "events.manage": false,
  "users.read": true,
  "users.manage": false
}

TTL: 300 segundos (5 minutos)

Invalidacion

El cache se invalida cuando:

  1. Se asigna/quita permiso - DELETE acl:permissions:{userId}
  2. Se cambia rol del usuario - DELETE acl:permissions:{userId}
  3. Usuario cierra sesion - DELETE acl:permissions:{userId}
  4. Manualmente (admin) - POST /api/acl/invalidate-cache

Verificacion en Backend

Middleware

En las rutas, se usa middleware:

// Ruta protegida
router.post("/events",
    authMiddleware,           // Verifica autenticacion
    checkPermission("events.manage"),  // Verifica permiso
    EventController.create    // Ejecuta accion
);

Si checkPermission falla: Retorna 403 Forbidden

Ejemplo de Codigo

// middleware/acl.ts
export const checkPermission = (permissionKey: string) => {
    return async (req, res, next) => {
        const hasAccess = await aclService.hasPermission(
            req.user.id,
            permissionKey
        );

        if (!hasAccess) {
            return res.status(403).json({
                error: "No tienes permiso para esta accion"
            });
        }

        next();
    };
};

Verificacion en Frontend

Hook de Permisos

// En React, usar hook:
const { hasPermission } = useAuth();

// Verificar antes de mostrar boton
{hasPermission('events.manage') && (
    <Button onClick={createEvent}>
        Crear Evento
    </Button>
)}

Carga de Permisos

Al iniciar sesion:

  1. Usuario se autentica
  2. Backend retorna permisos en response
  3. Frontend guarda en contexto
  4. Componentes usan hasPermission()

Actualizacion:

  • Cada 5 minutos (polling)
  • Al recibir notificacion de cambio
  • Al refrescar pagina

Errores de Permiso

401 Unauthorized

Codigo: 401

Mensaje: "No autenticado"

Causa:

  • No hay sesion activa
  • Token expirado
  • Cookie invalida

Solucion: Iniciar sesion nuevamente

403 Forbidden

Codigo: 403

Mensaje: "No tienes permiso para esta accion"

Causa:

  • Usuario no tiene el permiso requerido
  • Rol no compatible con la accion
  • Permiso explicitamente denegado

Solucion:

  • Solicitar el permiso a un admin
  • O usar cuenta con permisos adecuados

UI sin Permiso

En la interfaz, elementos sin permiso:

  • Opcion 1: No se muestran - El boton/menu no aparece
  • Opcion 2: Deshabilitados - El boton aparece pero gris/inactivo
  • Opcion 3: Mensaje al intentar - Modal: "No tienes permiso..."

Debugging de Permisos

Verificar Permisos de Usuario

Como admin:

  1. Menu: Administracion → Usuarios
  2. Buscar usuario
  3. Click [...] → Ver permisos
  4. Ver lista de permisos activos

O via API: GET /api/users/{userId}/permissions

Log de Verificacion

En desarrollo, habilitar logs:

[ACL] Checking: events.manage for user 456
[ACL] Cache: HIT
[ACL] Result: allowed = true

Comprobar Manualmente

Como admin, simular usuario:

  1. Menu: Administracion → Usuarios
  2. Buscar usuario
  3. Click [...] → Simular
  4. Navega como ese usuario
  5. Verifica que ve/no ve

Nota: Solo para debugging, no produccion.

Permisos Implicitos

Dependencias

Algunos permisos implican otros:

  • process.manage implica process.read - Si puedes gestionar, puedes ver (pero NO al reves)
  • events.manage implica events.read
  • users.manage implica users.read
  • ...

El sistema puede verificar automaticamente.

Cascada

Ejemplo:

Si usuario tiene: process.manage Y intenta: process.read

Verificacion:

  1. ¿Tiene process.read? → NO (no asignado)
  2. ¿Tiene process.manage? → SI
  3. process.manage implica process.read
  4. Resultado: PERMITIDO

Performance

Optimizaciones

El sistema optimiza verificaciones:

  1. Cache en Redis - Evita queries repetidas
  2. Carga en lote - Carga todos los permisos de usuario de una vez
  3. Verificacion local - Frontend verifica localmente cuando posible
  4. Prefetch - Carga permisos al iniciar sesion

Metricas

Tiempos tipicos:

EscenarioTiempo
Cache hit< 1ms
Cache miss10-50ms
Sin cache50-100ms

El 95% de verificaciones son cache hits.

Permisos

Para ver informacion de permisos: acl.read

Para modificar permisos: acl.manage

Proximos Pasos

¿No encontraste lo que buscabas?

Nuestro equipo de soporte está listo para ayudarte.

Contactar Soporte