Autenticación y Sesión
Visión General
LCS utiliza NextAuth.js v5 con estrategia JWT para autenticación. No se utilizan sesiones en base de datos — toda la información de sesión viaja en un token JWT firmado dentro de una cookie HTTP-only.
Flujo de Login
JWT Token — Contenido
El token JWT contiene toda la información necesaria para evaluación de permisos sin consultar la base de datos:
| Claim | Tipo | Descripción |
|---|---|---|
id | string | ID único del usuario (AspNetUsers.Id) |
userName | string | Nombre de usuario para login |
name | string | Nombre completo para mostrar |
role | string | Rol principal (Admin/Supervisor/Ejecutivo) |
permissions | string[] | Array de permisos efectivos resueltos |
lastActivity | number | Timestamp de última actividad (inactivity timeout) |
lastPasswordChangedDate | string | Para forzar cambio cada 60 días |
:::info Sin Datos Sensibles El JWT no contiene contraseñas, datos financieros, ni información personal de deudores. Solo contiene lo mínimo necesario para autenticación y autorización. :::
Control de Sesión
Timeout por Inactividad
Configuración (variables de entorno):
SESSION_INACTIVITY_MINUTES=30 # Timeout por inactividad
SESSION_MAX_AGE_MINUTES=480 # Máximo absoluto (8 horas)
Comportamientos
| Evento | Acción |
|---|---|
| Inactividad > 30 min | Sesión invalidada, redirige a login |
| Sesión > 8 horas | Cierre forzado independiente de actividad |
| Pestaña cerrada y reabierta | Si el cookie persiste y no expiró, continúa |
| Cambio de permisos por Admin | Toma efecto en próximo login del usuario |
Bloqueo de Cuenta
| Parámetro | Valor |
|---|---|
| Intentos antes de bloqueo | 5 |
| Duración del bloqueo | 5 minutos |
| Reset del contador | Login exitoso |
El bloqueo es automático e inapelable. Un administrador no puede desbloquear manualmente antes de los 5 minutos. Si se sospecha un ataque, se recomienda deshabilitar la cuenta desde la administración de usuarios.
Cambio Obligatorio de Contraseña
- La contraseña debe cambiarse cada 60 días
- El proxy intercepta TODAS las rutas y redirige si está expirada
- No se puede acceder a ninguna otra sección hasta completar el cambio
- El cambio actualiza
LastPasswordChangedDateen la DB - Las contraseñas se hashean con el algoritmo compatible con ASP.NET Identity
Invalidación de Sesiones Legacy
Las sesiones creadas antes de la implementación del sistema de permisos (sin campo permissions en el token) se invalidan automáticamente:
// En el JWT callback de NextAuth:
if (!Array.isArray(token.permissions)) {
return null // Fuerza re-login
}
Seguridad del Token
| Aspecto | Implementación |
|---|---|
| Almacenamiento | Cookie HTTP-only (no accesible por JavaScript) |
| Transmisión | Solo HTTPS (Secure flag) |
| Firmado | HMAC-SHA256 con secret |
| SameSite | Strict (protección CSRF) |
| Expiración | Controlada por maxAge en NextAuth config |
Archivos Clave
| Archivo | Propósito |
|---|---|
src/lib/auth.config.ts | Configuración de NextAuth + tipos de sesión |
src/lib/auth.ts | Providers, callbacks, resolución de permisos |
src/proxy.ts | Edge middleware (inactividad, password expiry) |
src/app/api/auth/[...nextauth]/route.ts | API route handler de NextAuth |
src/app/(auth)/login/page.tsx | Página de login |
src/app/(auth)/change-password/page.tsx | Página de cambio de contraseña |