erp-core/docs/04-modelado/requerimientos-funcionales/mgn-001/RF-MGN-001-007-session-management.md

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

  1. Usuario debe estar autenticado (tiene JWT válido)
  2. Redis debe estar disponible para almacenar tokens

Flujo Principal

  1. Usuario inicia sesión exitosamente (RF-MGN-001-001)
  2. Sistema genera access token (JWT, expira en 8h) con claims:
    • user_id, tenant_id, email, roles[], permissions[]
  3. Sistema genera refresh token (UUID, expira en 30 días)
  4. Sistema almacena refresh token en auth.sessions con:
    • token, user_id, expires_at, ip_address, user_agent
  5. Sistema retorna ambos tokens al cliente
  6. Cliente almacena tokens (localStorage o httpOnly cookie)
  7. Cliente usa access token en cada request (Authorization: Bearer {token})
  8. Cuando access token expira (8h), cliente usa refresh token
  9. Sistema valida refresh token en auth.sessions
  10. Sistema genera nuevo par de tokens (access + refresh)
  11. Sistema invalida refresh token anterior
  12. Cliente continúa usando nuevo access token

Flujos Alternativos

FA-1: Access Token Expirado

  1. Cliente envía request con access token expirado
  2. Sistema retorna error 401: "Token expirado"
  3. Cliente automáticamente usa refresh token para obtener nuevo access token
  4. Cliente reintenta request original con nuevo token

FA-2: Refresh Token Inválido o Expirado

  1. Cliente intenta renovar con refresh token inválido/expirado
  2. Sistema retorna error 401: "Sesión expirada. Inicie sesión nuevamente"
  3. Cliente redirige a login

FA-3: Logout Simple

  1. Usuario hace clic en "Cerrar sesión"
  2. Sistema invalida refresh token actual (marca como used_at=NOW())
  3. Sistema elimina token de Redis (si se usa caché)
  4. Cliente elimina tokens almacenados
  5. Usuario es redirigido a login

FA-4: Logout de Todos los Dispositivos

  1. Usuario solicita "Cerrar sesión en todos los dispositivos"
  2. Sistema invalida TODOS los refresh tokens del usuario
  3. Sistema elimina sesiones del usuario en Redis
  4. Todas las sesiones activas quedan invalidadas
  5. Usuario debe iniciar sesión nuevamente en todos los dispositivos

FA-5: Logout Forzado (Administrativo)

  1. Administrador desactiva usuario o cambia contraseña
  2. Sistema invalida todos los refresh tokens del usuario
  3. Usuario no puede renovar tokens
  4. Usuario debe iniciar sesión con nueva contraseña

FA-6: Detección de Token Robado (Reuse Detection)

  1. Sistema detecta intento de usar refresh token ya utilizado
  2. Sistema invalida TODOS los tokens del usuario (posible robo)
  3. Sistema registra evento de seguridad en audit_log
  4. 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
  • 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)