5.5 KiB
5.5 KiB
RF-MGN-001-007: Gestión de Sesiones
Módulo: MGN-001 - Fundamentos Prioridad: P0 (MVP) Story Points: 5 Estado: Definido Fecha: 2025-11-23
Descripción
El sistema debe gestionar sesiones de usuarios mediante JWT tokens con refresh tokens. Incluye creación, renovación, invalidación de tokens y logout en múltiples dispositivos.
Actores
- Actor Principal: Usuario autenticado
- Actores Secundarios: Sistema (gestión automática de tokens)
Precondiciones
- Usuario debe estar autenticado (tiene JWT válido)
- Redis debe estar disponible para almacenar tokens
Flujo Principal
- Usuario inicia sesión exitosamente (RF-MGN-001-001)
- Sistema genera access token (JWT, expira en 8h) con claims:
- user_id, tenant_id, email, roles[], permissions[]
- Sistema genera refresh token (UUID, expira en 30 días)
- Sistema almacena refresh token en auth.sessions con:
- token, user_id, expires_at, ip_address, user_agent
- Sistema retorna ambos tokens al cliente
- Cliente almacena tokens (localStorage o httpOnly cookie)
- Cliente usa access token en cada request (Authorization: Bearer {token})
- Cuando access token expira (8h), cliente usa refresh token
- Sistema valida refresh token en auth.sessions
- Sistema genera nuevo par de tokens (access + refresh)
- Sistema invalida refresh token anterior
- Cliente continúa usando nuevo access token
Flujos Alternativos
FA-1: Access Token Expirado
- Cliente envía request con access token expirado
- Sistema retorna error 401: "Token expirado"
- Cliente automáticamente usa refresh token para obtener nuevo access token
- Cliente reintenta request original con nuevo token
FA-2: Refresh Token Inválido o Expirado
- Cliente intenta renovar con refresh token inválido/expirado
- Sistema retorna error 401: "Sesión expirada. Inicie sesión nuevamente"
- Cliente redirige a login
FA-3: Logout Simple
- Usuario hace clic en "Cerrar sesión"
- Sistema invalida refresh token actual (marca como used_at=NOW())
- Sistema elimina token de Redis (si se usa caché)
- Cliente elimina tokens almacenados
- Usuario es redirigido a login
FA-4: Logout de Todos los Dispositivos
- Usuario solicita "Cerrar sesión en todos los dispositivos"
- Sistema invalida TODOS los refresh tokens del usuario
- Sistema elimina sesiones del usuario en Redis
- Todas las sesiones activas quedan invalidadas
- Usuario debe iniciar sesión nuevamente en todos los dispositivos
FA-5: Logout Forzado (Administrativo)
- Administrador desactiva usuario o cambia contraseña
- Sistema invalida todos los refresh tokens del usuario
- Usuario no puede renovar tokens
- Usuario debe iniciar sesión con nueva contraseña
FA-6: Detección de Token Robado (Reuse Detection)
- Sistema detecta intento de usar refresh token ya utilizado
- Sistema invalida TODOS los tokens del usuario (posible robo)
- Sistema registra evento de seguridad en audit_log
- Sistema notifica al usuario por email
Reglas de Negocio
- RN-1: Access token expira en 8 horas
- RN-2: Refresh token expira en 30 días
- RN-3: Refresh token solo puede usarse una vez (one-time use)
- RN-4: Usuario puede tener múltiples sesiones activas (diferentes dispositivos)
- RN-5: Cambio de contraseña invalida todas las sesiones
- RN-6: Desactivación de usuario invalida todas las sesiones
- RN-7: Sistema registra IP y user agent de cada sesión
- RN-8: Reuso de refresh token invalida todas las sesiones (seguridad)
Criterios de Aceptación
- Sistema genera access token (JWT, 8h) y refresh token (UUID, 30d) en login
- Access token contiene claims: user_id, tenant_id, roles, permissions
- Cliente puede renovar access token usando refresh token
- Refresh token solo puede usarse una vez
- Usuario puede cerrar sesión (invalida refresh token actual)
- Usuario puede cerrar sesión en todos los dispositivos
- Cambio de contraseña invalida todas las sesiones
- Sistema detecta reuso de refresh token y invalida todas las sesiones
- Sistema registra IP y user agent en auth.sessions
- Administrador puede ver sesiones activas de un usuario
Entidades Involucradas
- Principales:
- auth.sessions (refresh_token, user_id, expires_at, ip_address, user_agent, used_at)
- auth.users (usuario propietario de sesión)
- Relacionadas:
- Redis (caché de tokens para validación rápida)
Referencias
Notas Técnicas
- JWT Estructura:
{ "sub": "user_id", "tenant_id": 123, "email": "user@example.com", "roles": ["admin", "user"], "permissions": ["sale.order.create", "sale.order.read"], "iat": 1234567890, "exp": 1234596690 } - Refresh Token: UUID v4 almacenado en DB + Redis
- Redis Caché:
- Key:
session:refresh_token:{token} - Value:
{user_id, expires_at} - TTL: 30 días
- Key:
- Seguridad:
- httpOnly cookies (no accesible por JS)
- Secure flag (solo HTTPS)
- SameSite=Strict (prevenir CSRF)
- Backend: NestJS Guards + JWT Strategy
- Frontend: Axios interceptors para auto-refresh
Dependencias
- RF Dependientes: RF-MGN-001-001 (Autenticación)
- Bloqueante para: Todos los RF (sesión es requisito para operar)