Skip to main content
La autenticación de Comfaca Créditos combina sesiones de servidor gestionadas por nuxt-auth-utils con tokens JWT firmados con jose. La sesión de servidor se almacena en una cookie HttpOnly cifrada, mientras que el JWT viaja en el Authorization: Bearer header y se valida en cada recarga para confirmar que la sesión sigue siendo válida.

Flujo de Autenticación

1

Envío de credenciales

El cliente realiza POST /api/auth/login con { username, password }. Zod valida el cuerpo antes de que llegue al servicio: username debe tener al menos 3 caracteres y password al menos 8.
2

Verificación con bcrypt

authService.validateCredentials() busca al usuario en la base de datos por username y compara la contraseña con el hash almacenado usando bcrypt.compareSync(password, password_hash).
3

Creación de la sesión de servidor

Si las credenciales son válidas, setUserSession(event, { user: userSession, loggedInAt: new Date() }) de nuxt-auth-utils escribe la sesión en una cookie segura. La sesión tiene una duración máxima de 8 horas (auth.session.maxAge: 60 * 60 * 8).
4

Emisión del JWT

En paralelo, authService.createToken(user) genera un JWT HS256 con expiración de 24 horas, firmado con NUXT_JWT_SECRET. El payload incluye sub (ID numérico del usuario), email y roles[]. El issuer y audience son "sistema-creditos" y "sistema-creditos-users" respectivamente.
5

Respuesta al cliente

El endpoint devuelve { user, access_token, token_type: "bearer" }. El cliente almacena el token en el store de sesión (SessionData.accessToken) y lo adjunta en el header Authorization para las llamadas posteriores.
6

Verificación periódica

El middleware del cliente llama a GET /api/auth/verify en cada navegación protegida. El endpoint valida el JWT, comprueba que el sub coincide con la sesión activa y devuelve los datos actualizados del usuario (incluido trabajador si aplica).

Estructura de Sesión

Sesión de servidor (nuxt-auth-utils)

La cookie de sesión contiene el objeto User definido en shared/auth.d.ts:

Sesión del cliente

El store del cliente (SessionData) definido en shared/types/session.ts es la fuente de verdad en el frontend:

Payload del JWT


Middleware del Servidor

Los middleware de servidor corren en orden para cada request a /api/*.

server/middleware/auth.ts

Protege todas las rutas de la API excepto las rutas públicas declaradas en la lista blanca. Inyecta el usuario autenticado en event.context.user para que los handlers lo consuman sin re-leer la cookie.

server/middleware/admin.ts

Aplica exclusivamente a las rutas bajo /api/admin. Verifica que el usuario tenga el rol "administrator" en la sesión.

server/middleware/validateSolicitudLimit.ts

Aplica solo a los endpoints POST /api/solicitudes/guardar-solicitud y POST /api/solicitudes/enviar-solicitud. Consulta la configuración limite_solicitudes en base de datos y bloquea la creación si el usuario ya alcanzó el número máximo de solicitudes activas (estados: guardada, enviada, en_revision, revision_comite).
Si falla la consulta a la tabla de configuraciones (error de infraestructura), el middleware no bloquea la operación. El principio aplicado es fail open para no degradar la experiencia ante errores transitorios de base de datos.

Middleware del Cliente

El middleware solo corre en el cliente (import.meta.server guard) para evitar ejecución durante SSR. La lógica de qué rutas requieren autenticación y qué roles tienen acceso a qué rutas está centralizada en app/config/auth.config.ts (shouldApplyAuthMiddleware y hasPermissionForRoute).

Roles y Permisos

Rol asignado automáticamente al registrarse. Permite gestionar sus propias solicitudes de crédito.Permisos:
  • applications.create
  • applications.edit
  • applications.delete
  • applications.view_own
Acceso:
  • Dashboard del afiliado (/dash/*)
  • Gestión de solicitudes propias
  • Carga y descarga de documentos propios
  • Edición de perfil
Rol para usuarios de tipo empresa. Tiene los mismos permisos de operación sobre solicitudes que user_trabajador.Permisos:
  • applications.create
  • applications.edit
  • applications.delete
  • applications.view_own
Rol para funcionarios de Comfaca que gestionan solicitudes. Puede ver todas las solicitudes, aprobar/rechazar y gestionar convenios y firmas.Permisos:
  • applications.create, applications.edit, applications.delete
  • applications.view_all, applications.approve, applications.reject
  • solicitudes.manage, solicitudes.view
  • convenios.manage, convenios.view
  • firmas.manage, firmas.view
  • system.admin
Acceso completo. Puede gestionar usuarios, roles y toda la configuración del sistema.Permisos:
  • users.create, users.edit, users.delete, users.view
  • applications.create, applications.edit, applications.delete, applications.view_all
  • roles.manage
  • system.admin
Acceso adicional:
  • Panel administrativo completo (/admin/*)
  • Gestión de usuarios y roles
  • Gestión de convenios
  • Inicio de proceso de firma digital
  • Configuración del sistema

Seguridad

  • Hashing de contraseñas: bcrypt con factor de coste 10 (bcrypt.hashSync(password, 10)).
  • Sesiones HttpOnly: nuxt-auth-utils almacena la sesión en una cookie cifrada y HttpOnly, inaccesible desde JavaScript del cliente.
  • Expiración de sesión: 8 horas (auth.session.maxAge). El JWT tiene expiración de 24 horas pero la sesión de servidor expira primero.
  • Firma JWT: algoritmo HS256 con clave secreta de NUXT_JWT_SECRET. Issuer y audience son validados en cada verificación.
  • Validación de entradas: Zod valida todos los cuerpos de request en los endpoints de autenticación antes de llegar a la lógica de servicio.
  • CORS: Nitro hereda la configuración de CORS del preset node-server. En producción se recomienda restringir los Access-Control-Allow-Origin a los dominios propios.
  • Cooldown de reenvío de PIN: 30 segundos entre solicitudes de reenvío de código de verificación (RESEND_COOLDOWN_MS = 30_000).
Las variables NUXT_SESSION_PASSWORD y NUXT_JWT_SECRET deben ser cadenas aleatorias de alta entropía (mínimo 32 caracteres) en entornos de producción. Nunca las reutilices entre entornos ni las almacenes en el repositorio. Usa un gestor de secretos o variables de entorno del servidor.