Saltar al contenido principal

Autenticación y Seguridad

Este módulo regula el acceso de usuarios existentes al sistema, garantizando la persistencia de la sesión mediante estándares JWT y la integridad de los datos según el rol.


1. Flujo de Acceso (Miro)

A continuación, se presenta el diagrama de flujo diseñado para el proceso de Login, Recuperación de cuenta.

Instrucciones: Puedes navegar y hacer zoom directamente en el diagrama superior para ver los estados de error y validaciones.

1.1 Resumen textual (fallback sin Miro)

  • Login: email + password → valida credenciales → emite cookies HttpOnly (accessToken, refreshToken) y redirige por rol.
  • Recuperación: solicita email → envía token temporal (15-30 min) → reset → invalida sesiones previas.
  • Social Login: Google Auth → si email existe, une cuentas; si no, crea flujo de onboarding.
  • Bloqueo: 5 intentos fallidos → bloqueo temporal/captcha.

1.2 Relación con Registro

  • Scope contractual congelado (V1): ver ../04-Marco-Metodologico/32-contratos-registro-autenticacion-v1.md.
  • Los endpoints /api/v1/auth/register, /api/v1/auth/token/verify, /api/v1/auth/token/resend están detallados en el módulo Registro y Onboarding (UX, validaciones, casos de borde). Aquí se listan solo para completitud del servicio de sesión.
  • Políticas de OTP, rate limits y NFR compartidas aplican a ambos módulos.
  • POST /api/v1/auth/token/verify emite sesión inicial por cookies HttpOnly (accessToken, refreshToken).

1.2 Snapshot (offline)

Flujo de autenticación

Ver en pantalla completa


2. Arquitectura de Seguridad

2.1 Gestión de Sesiones (JWT)

El sistema utiliza un esquema de Dual Token:

  • Access Token: Emitido en cookie HttpOnly (accessToken). Caducidad: 15 min.
  • Refresh Token: Emitido en cookie HttpOnly (refreshToken). Caducidad: 7 dias. Secure/SameSite dependen de entorno (local: Secure=false, SameSite=Lax; prod: Secure=true, SameSite=Strict).

2.2 Registro de Auditoría

Toda acción de autenticación debe generar un log:

  • Intentos fallidos por IP.
  • Cambio de contraseña exitoso.
  • Vinculación/Desvinculación de cuentas de Google.

3. Métodos de Acceso y Sesión

3.1 Credenciales (Fase 1)

  • Identificador: Correo electrónico verificado.
  • Seguridad: Uso de JWT (JSON Web Tokens) con tiempo de expiración corto (ej. 1 hora) y Refresh Tokens para mantener la sesión activa sin re-autenticación constante.

3.2 Login Social con Google (V1)

La autenticacion con Google es parte del flujo de la version actual. Se documenta con el patron validado en celeb-be-v1.

3.2.1 Flujo tecnico (Google OAuth 2.0 Authorization Code)

  1. Front inicia OAuth
    • Inicia con Google SDK o URL OAuth (openid email profile).
    • Envia state firmado con origin (dominio frontend permitido).
  2. Callback en backend
    • GET /api/v1/auth/oauth2/google/callback?code=...&state=...
    • Backend valida state, origin y lista blanca de origins.
  3. Intercambio y validacion del token de Google
    • Backend intercambia code por tokens en Google (client_id, client_secret, redirect_uri).
    • Valida id_token (issuer/audience/exp/email_verified).
  4. Resolucion de cuenta local
    • Si usuario existe por email: inicia sesion y vincula proveedor si aplica.
    • Si no existe: crea cuenta base y deriva a onboarding corto.
  5. Sesion local
    • Siempre se emite sesion local (cookies accessToken + refreshToken), nunca se reutilizan tokens de Google.

3.2.2 Vinculacion de cuenta existente

  • Endpoint: POST /api/v1/auth/oauth2/google/link (requiere sesion activa).
  • Payload esperado: id_token de Google.
  • Uso: unir cuenta local existente con proveedor Google sin crear nueva cuenta.

3.2.3 Casos de borde / UX

  • Cancelacion en Google: mostrar error no bloqueante y permitir login normal.
  • email_verified=false: rechazar login social y solicitar flujo por correo.
  • state invalido o origin no permitido: rechazar con 401/403.
  • Correo asociado a otra identidad incompatible: devolver 409 y guiar a recuperacion.

3.2.4 Variables de entorno y seguridad

  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET
  • GOOGLE_REDIRECT_URI
  • GOOGLE_ALLOWED_ORIGINS (lista blanca)
  • Recomendacion: no aceptar callback desde dominios no registrados y auditar google_auth_success/google_auth_failed.

4. Recuperación de Cuenta

  • Flujo: El usuario solicita "Olvidé mi contraseña" -> Recibe un enlace con un token de corta duración (15-30 min) -> Define nueva contraseña.
  • Regla de Seguridad: Al cambiar la contraseña, se deben invalidar todas las sesiones activas en otros dispositivos.

5. Detalles Críticos

  • Bloqueo por Intentos: Tras 5 intentos fallidos, bloquear el login para esa IP/Correo temporalmente (5 min) o disparar un captcha para prevenir ataques de fuerza bruta.
  • Invalidación de Sesión: Al realizar un "Reset Password", todos los tokens activos en otros dispositivos deben ser invalidados.

5.1 Diccionario UX-Técnico por Pantalla

PantallaElemento UIID Técnico (API)ValidaciónMensaje UX en Error
LoginInput emailemailFormato email válido"Revisa tu correo"
LoginInput contraseñapasswordMín 8, mayúscula, número"Contraseña inválida"
LoginBotón ingresarlogin_submitDeshabilitar si campos vacíos"Completa los campos"
LoginCheckbox Recuérdameremember_meOpcional; extiende refresh""
LoginLink Recuperar contraseñaforgot_ctaNavega a Forgot""
ForgotInput emailemailEmail requerido"Ingresa tu correo para enviarte el enlace"
ResetInput nueva contraseñanew_passwordMín 8, mayúscula, número"Contraseña débil"
ResetInput confirmarconfirm_passwordDebe coincidir"Las contraseñas no coinciden"
Captcha/BloqueoWidget captchacaptcha_tokenObligatorio tras bloqueo"Confirma que no eres un robot"
Social LoginBotón Googlegoogle_oauthManejar cancelación"Inicia con Google o usa tu correo"

6. Lógica de Redirección (Post-Login)

Tras un login exitoso, el sistema debe redirigir según el arreglo roles del perfil de sesión.

RolDestinoRazón UX
PACIENTE/homeAcceso directo al buscador de servicios.
DOCTOR (Profesional de la Salud)/doc/dashboardGestión operativa inmediata (Citas/Perfil).
ENTITY_ADMIN/entity/dashboardGestión operativa inmediata (Citas/Perfiles).
CATALOG_ADMIN/admin/catalogsGestión operativa de catálogos maestros.
SUPERADMIN/admin/statsPanel de control y validación de profesionales.
  • Redirección por Rol:
    • Paciente -> /home
    • Profesional de Salud -> /doc/dashboard
    • Entidad -> /entity/dashboard
    • CatalogAdmin -> /admin/catalogs
    • SuperAdmin -> /admin/stats
  • Manejo de Errores: Diferenciar entre "Usuario no encontrado" y "Contraseña incorrecta" de forma genérica para seguridad ("Credenciales inválidas").

7. Especificaciones Técnicas (Pre-vía Swagger)

Estos endpoints representan el contrato inicial entre Front y Back. En V1, la sesión se transporta con cookies HttpOnly y las respuestas no exponen tokens.

Implementación Backend (Go, DDD + Clean Architecture):

  • Handlers en interfaces/http traducen DTOs de login/refresh/forgot/reset a use cases Login, RefreshToken, ForgotPassword, ResetPassword, Logout en application/auth.
  • Repositorios (UserRepo, TokenRepo, OtpRepo) son interfaces definidas en domain/application; implementaciones viven en infrastructure/persistence (Postgres/Redis) y infrastructure/notifications.
  • Entidades y lógica de sesión están en domain; los DTOs expuestos en OpenAPI no dependen de estructuras de persistencia.
  • Nomenclatura y estructura completas: ver arquitectura-y-despliegue.md §7.1.

Endpoints de Sesión

Base path: /api/v1

RecursoMétodoDescripción
/api/v1/auth/loginPOSTValida credenciales, emite cookies de sesión y devuelve perfil (401/422).
/api/v1/auth/logoutPOSTInvalida sesion usando accessToken en cookie (fallback Authorization: Bearer para compatibilidad).
/api/v1/auth/refreshPOSTRota sesión usando refreshToken en cookie (401/409).
/api/v1/auth/forgot-passwordPOSTEnvía email con token temporal (422).
/api/v1/auth/reset-passwordPOSTRecibe token y nueva contraseña (400/401/422).
/api/v1/auth/oauth2/google/callbackGETCallback OAuth de Google (intercambia code, valida state/origin).
/api/v1/auth/oauth2/google/linkPOSTVincula Google con cuenta autenticada usando id_token.

Parámetros exactos de seguridad (AUTH-CTR-004/005)

ControlEndpoint(s)Valor exacto
Access token TTL/api/v1/auth/login, /api/v1/auth/token/verify, /api/v1/auth/refresh900s (15 min)
Refresh token TTL/api/v1/auth/login, /api/v1/auth/token/verify, /api/v1/auth/refresh604800s (7 días) en cookie HttpOnly; Secure/SameSite por entorno (local: false/Lax, prod: true/Strict)
Rate limit login/api/v1/auth/login10 solicitudes por 300s (5 min) por email+ip
Intentos fallidos máximos login/api/v1/auth/login5 intentos; bloqueo 300s (5 min) y captcha al desbloquear
Rate limit forgot-password/api/v1/auth/forgot-password3 solicitudes por 900s (15 min) por email+ip
Rate limit reset-password/api/v1/auth/reset-password5 solicitudes por 900s (15 min) por email+ip
TTL reset token/api/v1/auth/forgot-password, /api/v1/auth/reset-password900s (15 min)
OTP TTL compartido con registro/api/v1/auth/token/verify, /api/v1/auth/token/resend900s (15 min)
OTP verify intentos/cooldown/api/v1/auth/token/verify, /api/v1/auth/token/resendverify: 5 intentos (bloqueo 1800s); resend: cooldown 60s, máximo 3 en 900s
Política de refresh reuse/api/v1/auth/refresh409 + REFRESH_REUSE; revocar todos los refresh tokens; invalidar todas las sesiones; forzar re-login; registrar evento REFRESH_REUSE; captcha en siguiente login

Contrato completo: ver API Swagger en Marco Metodológico o visitar /swagger desde la navbar. Códigos de error (resumen)

Endpoint400401409422
/auth/login-Credenciales inválidas-Datos inválidos
/auth/refresh-Token expirado/inválidoReuse detectado-
/auth/forgot-password---Email inválido
/auth/reset-passwordDatos faltantesToken inválido/expirado-Contraseña inválida

Catalogo de errores obligatorio (canonico)

Esta modulo debe responder con el formato y codigos definidos en 11-swagger-ui.md ("Catalogo canonico de errores API").

EscenarioCodigo canonicoHTTP
Credenciales invalidasUNAUTHORIZED401
Usuario bloqueado por abusoRATE_LIMITED429
Token refresh reutilizadoCONFLICT409
Payload login/reset invalidoVALIDATION_ERROR422
Proveedor OAuth no disponibleUPSTREAM_ERROR502

8. Requerimientos No Funcionales (NFR)

  • P95 login < 300ms; refresh < 200ms; reset-password < 400ms.
  • Tasa 401/422 < 2% semanal; tasa de reset exitoso > 95%.
  • Logs/trazas con trace_id, user_id, email, ip, route.
  • Compartidos con Registro: OTP delivery >98% en <30s, P95 verify <350ms.

8.1 SLIs/SLOs y Alertas

MétricaSLOAlerta
login_p95< 300msWarn > 350ms 5m; Crit > 500ms 5m
refresh_p95< 200msWarn > 250ms 5m
reset_success_rate> 95% semanalCrit < 90%
otp_delivery_success> 98% en <30sWarn < 95% o latencia >45s
rate_limit_blocked< 0.5% de intentosWarn > 1%

8.2 Ejemplos de Requests/Responses

  • Login (POST /api/v1/auth/login)
    • Request: { "email": "user@mail.com", "password": "Secret123" }
    • Response 200: { "user": {"roles": ["PATIENT","DOCTOR"]} }
    • Response 401: { "message": "Credenciales inválidas" }
  • Refresh (POST /api/v1/auth/refresh)
    • Request: sin body (cookie refreshToken); body opcional solo para compatibilidad legacy.
    • 409 (reuse): { "message": "Refresh token reused" }
  • Forgot/Reset
    • Request forgot: { "email": "user@mail.com" }
    • Reset 400/422: { "message": "Token inválido o expirado" }

9. Checklist de Seguridad

  • Refresh rotation obligatoria; detectar reuse → invalidar sesión y registrar REFRESH_REUSE.
  • Tokens de reset/OTP siempre hash; TTL exactos según tabla "Parámetros exactos de seguridad (AUTH-CTR-004/005)".
  • Rate limits, cooldowns, intentos máximos y lockouts deben cumplir los valores exactos de la tabla "Parámetros exactos de seguridad (AUTH-CTR-004/005)".
  • Cookies de sesion (accessToken, refreshToken): HttpOnly; Secure/SameSite por entorno (local: false/Lax, prod: true/Strict); CORS solo dominios oficiales.
  • MFA opcional para Admin/Profesional de Salud (guardar secreto cifrado en BD).
  • Compartidos con Registro: rate limit /api/v1/auth/token/verify 5 req/15min; masking de email/phone en errores; no loggear PII/PHI.

10. Secuencia de Sesión (referencial)

Ejemplo de Respuesta Exitosa (Login)

{
"status": "success",
"data": {
"token": "eyJhbGciOiJIUzI1...",
"user": {
"id": "uuid-123",
"email": "doctor@ejemplo.com",
"roles": ["PATIENT", "DOCTOR"],
"status": "ACTIVE",
"onboarding_completed": true
}
}
}

11. QA / Testing Funcional

  • Login: credencial válida/incorrecta; cuenta bloqueada por intentos; captcha tras bloqueo.
  • Refresh: token expirado, reuse detectado, cookie ausente, device distinto.
  • Forgot/Reset: token expirado, ya usado, contraseña débil, confirmación distinta.
  • Social Login: usuario nuevo vs existente con mismo email; revocación de consentimiento.
  • Logout: invalida refresh y access; sesión paralela en otro dispositivo.

12. Variables de Entorno (Front)

  • VITE_API_BASE=https://api.example.com/api/v1 (prod)
  • VITE_API_BASE=http://localhost:8080/api/v1 (local)
  • VITE_GOOGLE_CLIENT_ID=...
  • VITE_ENABLE_MFA=true|false

13. Accesibilidad (A11y)

  • Formularios navegables con teclado; foco visible en inputs y botones primarios.
  • Mensajes de error en texto, asociados al campo (aria-describedby).
  • Contraste AA en botones/links y estados de error/success.
  • Soportar lector de pantalla en captcha y MFA (códigos numéricos).

14. Control de Abuso y Fraude

  • Rate limits por IP y por cuenta; lista gris para comportamientos sospechosos.
  • Captcha adaptativo tras 3-5 intentos fallidos o patrones anómalos.
  • Registro de dispositivo (fingerprint ligero) para alertar cambios drásticos.
  • Alertas de login desde nueva IP/ubicación con opción de cerrar todas las sesiones.

14.1 Uso de Captcha / reCAPTCHA

  • Cuándo dispararlo:
    • Login: a partir del 5o intento fallido por IP/correo o señales de bot (UA anómalo, alta frecuencia).
    • Refresh reuse detectado: obligar captcha en el siguiente login.
    • Forgot/Reset: tras 3 solicitudes fallidas de reset en 15 min.
    • Social Login: si el proveedor devuelve cancelaciones repetidas (posible scripting).
  • Cómo validarlo:
    • Front obtiene captcha_token (reCAPTCHA v3 o hCaptcha) y lo envía en el header X-Captcha-Token.
    • Backend valida server-to-server contra el proveedor y rechaza si score < 0.5 o si está ausente cuando es requerido.
  • UX: mostrar mensaje claro “Completa la verificación para continuar” y permitir reintento sin perder el formulario.
  • Observabilidad: loggear captcha_required=true, captcha_passed y score (sin exponer el token).

15. Definition of Done (Seguridad)

  • Contraseñas hasheadas con Argon2 o BCrypt.
  • Headers de seguridad configurados (CORS, Helmet, HSTS).
  • No se devuelven datos sensibles (ej. ID de base de datos o contraseñas) en los JSON de respuesta.
  • El sistema bloquea el acceso tras X intentos fallidos.

16. Definición y Propósito

Garantizar que usuarios ya registrados obtengan acceso seguro y persistente a su rol (Paciente, Profesional de Salud, Entidad, Admin) mediante credenciales o login social, minimizando riesgo de secuestro de sesión y manteniendo cumplimiento de NFR/seguridad.

17. Actores y Permisos (RBAC)

Rol¿Puede iniciar sesión?Restricciones / Notas
PacienteSolo scopes de paciente; no acceso a gestión de citas de otros.
Profesional de SaludRequiere cuenta verificada; puede ver su agenda, reseñas y notificaciones profesionales.
EntidadAccede a dashboards de sucursal/afiliación; requiere relación aprobada.
AdminMFA recomendado; acceso a panel de auditoría y validación.

18. Reglas de Negocio

  • Bloqueo temporal tras 5 intentos fallidos; desbloqueo automático o vía captcha.
  • Refresh token reuse → invalidar sesión en todos los dispositivos y registrar evento REFRESH_REUSE.
  • Reset password invalida todas las sesiones activas.
  • Social login (Google): si el correo existe, se vincula; si no, se crea cuenta siguiendo onboarding.
  • MFA opcional/obligatorio para Admin y Profesional de Salud según política.

19. Acciones Técnicas y Eventos (Backend)

  • login_success, login_failed, account_locked, refresh_reuse_detected.
  • forgot_requested, reset_success, reset_failed.
  • social_linked, social_unlinked, mfa_enabled, mfa_challenge_failed. Cada evento debe emitirse a logs con trace_id y a métricas/OTel donde aplique.

20. Casos de Borde y Manejo de Errores

  • Usuario inexistente o inactivo → respuesta genérica de credenciales inválidas.
  • Cuenta bloqueada por intentos → devolver estado bloqueado y requerir captcha.
  • Refresh expirado o reuse → forzar re-login y registrar incidente.
  • Token de reset expirado o usado → error 401/422 y opción de reenviar.
  • Social login cancelado por el usuario → mostrar mensaje no intrusivo y permitir reintento.

21. Mermaid: Flujo de Navegación

22. Roles, claims y auditoría

  • Roles son acumulativos: un access token puede incluir PATIENT, DOCTOR y/o ENTITY_ADMIN; el backend valida scopes sin retirar el rol paciente.
  • Los claims del token deben incluir sub, email, roles, country_code y locale (si ya existen en perfil).
  • Emitir eventos ROLE_GRANTED y USER_PROFILE_UPDATED con changed_by, timestamp e IP/UA al otorgar roles o modificar perfil.
  • PII: phone debe cifrarse/mascararse en logs y jamás viajar en texto plano fuera de HTTPS.

23. Criterios de Aceptación por Paso

PasoCriterioAceptación
LoginCredenciales válidas devuelven access+refresh y rol200 con tokens y perfil
Login fallidoTras 5 intentos se bloquea durante 5 min o se pide captcha429 o 423 controlado
RefreshCon refresh válido se entrega nuevo access200 y rotation exitosa
Forgot/ResetToken válido permite cambiar contraseña; invalida sesiones previas200 y login requerido
Social loginCuenta existente se vincula; nueva crea perfil200 con perfil correcto

24. Fallback de Proveedor de Email

  • Primario: proveedor configurado (p.ej. SendGrid); fallback: SES/SMTP.
  • Reintentos exponenciales hasta 3 veces; si falla, log crítico y mensaje amigable al usuario.
  • Plantillas transaccionales versionadas; no exponer detalles técnicos en la UI.

25. Métricas de Producto (Funnel)

  • CTR de acceso al login desde landing/app.
  • Conversión login éxito / intentos totales.
  • Tasa de recuperación de cuenta exitosa / solicitudes.
  • Abandono en captcha o MFA.
  • Reuse de refresh detectado por semana.

26. Enlaces y Trazabilidad

  • Swagger UI: /swagger.html (acceso desde /swagger) y contrato YAML en /openapi.yaml.
  • Doc de Registro y Onboarding: ../05-Producto/registro (flujo y OTP compartidos).
  • Roadmap técnico: ../04-Marco-Metodologico/roadmap-tecnico (IDs API-01 y UX-01).
  • Diseños UI: Miro y snapshots en /miro/auth-login.jpg.