Visión General de la Arquitectura
Este documento proporciona una visión general de los patrones arquitectónicos y decisiones de diseño implementados en la API de Autenticación SaaS.
Principios Arquitectónicos
La API de Autenticación SaaS sigue los principios de Arquitectura Limpia (también conocida como Arquitectura Hexagonal o de Puertos y Adaptadores) para garantizar:
- Separación de Responsabilidades: Límites claros entre diferentes partes de la aplicación
- Inversión de Dependencias: Las dependencias apuntan hacia adentro, con el dominio en el centro
- Capacidad de Prueba: Los componentes son fáciles de probar de forma aislada
- Flexibilidad: Facilidad para intercambiar implementaciones (por ejemplo, base de datos, caché, etc.)
- Mantenibilidad: Una organización clara hace que el código sea más fácil de mantener
Arquitectura de Alto Nivel
La aplicación se divide en varias capas:
┌─────────────────────────────────────────────────────────────────┐│ ││ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ ││ │ │ │ │ │ │ ││ │ Capa de │ ──> │ Capa de │ ──> │ Modelos de │ ││ │ Interfaz │ │ Aplicación │ │ Dominio e │ ││ │ │ │ │ │ Interfaces │ ││ └─────────────┘ └─────────────┘ └─────────────────┘ ││ │ │ Λ ││ │ │ │ ││ │ ▼ │ ││ │ ┌─────────────┐ │ ││ │ │ │ │ ││ └────────────>│ Servicios │────────────┘ ││ │ de Dominio │ ││ │ │ ││ └─────────────┘ ││ │ ││ ▼ ││ ┌─────────────────┐ ││ │ │ ││ │ Capa de │ ││ │ Infraestructura │ ││ │ │ ││ └─────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘
Capas
-
Capa de Dominio
- Entidades y lógica de negocio principales
- Interfaces de dominio (repositorios, servicios)
- Sin dependencias de otras capas o frameworks externos
-
Capa de Aplicación
- Casos de uso/servicios que implementan la lógica de negocio
- Coordina las entidades de dominio
- Solo depende de la capa de dominio
-
Capa de Infraestructura
- Implementa las interfaces de dominio
- Contiene adaptadores para sistemas externos (base de datos, caché, etc.)
- Depende de la capa de dominio (implementa sus interfaces)
-
Capa de Interfaz
- Manejadores y rutas HTTP
- Formato de solicitudes/respuestas
- Validación de entrada
- Depende de la capa de aplicación
Estructura del Proyecto
El proyecto sigue una estructura de directorios orientada al dominio:
saas-auth-api/├── cmd/ # Puntos de entrada de la aplicación│ └── api/ # Aplicación API principal│ └── main.go # Inicialización de la aplicación├── config/ # Configuración│ └── config.yaml # Archivo de configuración├── docs/ # Documentación│ └── swagger.yaml # Documentación de la API├── internal/ # Núcleo de la aplicación│ ├── apiKey/ # Dominio de claves API│ │ ├── application/ # Casos de uso de claves API│ │ ├── domain/ # Modelos de dominio e interfaces de claves API│ │ ├── infrastructure/ # Implementaciones de repositorios de claves API│ │ └── interfaces/ # Manejadores HTTP y rutas de claves API│ ├── auth/ # Dominio de autenticación│ │ ├── application/ # Casos de uso de autenticación│ │ ├── domain/ # Modelos de dominio e interfaces de autenticación│ │ ├── infrastructure/ # Implementaciones de repositorios de autenticación│ │ └── interfaces/ # Manejadores HTTP y rutas de autenticación│ ├── role/ # Dominio de roles y permisos│ │ ├── application/ # Casos de uso de roles│ │ ├── domain/ # Modelos de dominio e interfaces de roles│ │ ├── infrastructure/ # Implementaciones de repositorios de roles│ │ └── interfaces/ # Manejadores HTTP y rutas de roles│ └── user/ # Dominio de usuarios│ ├── application/ # Casos de uso de usuarios│ ├── domain/ # Modelos de dominio e interfaces de usuarios│ ├── infrastructure/ # Implementaciones de repositorios de usuarios│ └── interfaces/ # Manejadores HTTP y rutas de usuarios├── migrations/ # Migraciones de base de datos├── pkg/ # Paquetes compartidos│ ├── config/ # Carga de configuración│ ├── database/ # Conexión a base de datos y repositorios│ ├── logger/ # Utilidades de registro│ ├── middleware/ # Middlewares HTTP│ └── validator/ # Validación de entrada└── tests/ # Pruebas ├── e2e/ # Pruebas de extremo a extremo ├── integration/ # Pruebas de integración └── unit/ # Pruebas unitarias
Componentes Clave
Modelos de Dominio
Cada área de dominio tiene sus propios modelos que representan entidades de negocio fundamentales:
- User: Representa un usuario autenticado
- Role: Representa un conjunto de permisos
- Permission: Representa una acción que puede realizarse
- APIKey: Representa una clave API para autenticación
Repositorios
Los repositorios proporcionan una capa de abstracción para el acceso a datos:
- UserRepository: Acceso a datos de usuarios
- RoleRepository: Acceso a datos de roles
- PermissionRepository: Acceso a datos de permisos
- APIKeyRepository: Acceso a datos de claves API
- AuthRepository: Acceso a datos de autenticación (tokens, sesiones)
Servicios
Los servicios implementan la lógica de negocio:
- AuthService: Autenticación y autorización
- UserService: Gestión de usuarios
- RoleService: Gestión de roles y permisos
- APIKeyService: Gestión de claves API
Manejadores HTTP
Los manejadores HTTP procesan solicitudes y devuelven respuestas:
- AuthHandler: Endpoints de autenticación
- UserHandler: Endpoints de gestión de usuarios
- RoleHandler: Endpoints de gestión de roles
- APIKeyHandler: Endpoints de gestión de claves API
Middleware
Las funciones middleware procesan las solicitudes antes de que lleguen a los manejadores:
- JWT Middleware: Autenticación JWT
- API Key Middleware: Autenticación con clave API
- RBAC Middleware: Control de acceso basado en roles
- Rate Limit Middleware: Limitación de tasa de solicitudes
Flujo de Datos
Flujo de Autenticación
- El cliente envía credenciales a
/auth/login
- AuthHandler recibe la solicitud
- AuthService valida las credenciales
- AuthService genera tokens JWT
- AuthRepository almacena el token de refresco en Redis
- AuthHandler devuelve los tokens al cliente
Flujo de Autorización
- El cliente envía una solicitud autenticada con JWT o clave API
- JWTMiddleware o APIKeyMiddleware valida la autenticación
- RBACMiddleware verifica los permisos
- La solicitud se procesa si está autorizada
- Las solicitudes no autorizadas son rechazadas con estado 401 o 403
Esquema de Base de Datos
La aplicación utiliza una base de datos PostgreSQL con las siguientes tablas principales:
- users: Información de usuarios
- roles: Definiciones de roles
- permissions: Definiciones de permisos
- role_permissions: Relaciones rol-permiso
- user_roles: Relaciones usuario-rol
- api_keys: Información de claves API
- api_key_permissions: Relaciones clave API-permiso
- audit_logs: Eventos de seguridad y auditoría
Dependencias Externas
La aplicación depende de los siguientes sistemas externos:
- PostgreSQL: Almacenamiento de datos principal
- Redis: Almacenamiento de caché y sesiones
- Docker: Contenedorización
- Fiber: Framework HTTP
- JWT: Tokens de autenticación
Consideraciones de Escalabilidad
La arquitectura soporta escalado horizontal:
- Diseño Sin Estado: No se almacena estado de sesión en la aplicación
- Agrupación de Conexiones: Las conexiones a base de datos y Redis están agrupadas
- Caché: Redis se utiliza para cachear datos frecuentemente accedidos
- Limitación de Tasa: Limitación de tasa distribuida usando Redis
Arquitectura de Seguridad
La seguridad se implementa en múltiples niveles:
- Autenticación: Tokens JWT y claves API
- Autorización: Control de acceso basado en roles
- Validación de Entrada: Toda la entrada es validada
- Seguridad de Contraseñas: Hashing bcrypt con salt
- Gestión de Tokens: Expiración y rotación de tokens
- Limitación de Tasa: Protección contra ataques de fuerza bruta
Monitorización y Observabilidad
La aplicación proporciona:
- Registro: Registro estructurado con control de nivel
- Comprobaciones de Salud: Endpoint HTTP para monitorización de salud
- Seguimiento de Errores: Respuestas de error estandarizadas
- Estadísticas de Base de Datos: Estadísticas de grupo de conexiones
- Estadísticas de Redis: Métricas de conexión y operación
Arquitectura de Despliegue
La aplicación puede desplegarse en varias configuraciones:
Despliegue Simple
┌───────────┐ ┌───────────┐ ┌───────────┐│ │ │ │ │ ││ API │───>│ PostgreSQL│ │ Redis ││ Contenedor│ │ │ │ ││ │ └───────────┘ └───────────┘└───────────┘ Λ Λ │ │ └───────────────┘
Despliegue Escalable
┌───────────┐│ ││Balanceador││ de Carga ││ │└───────────┘ │ ▼┌───────────┐ ┌───────────┐ ┌───────────┐│ │ │ │ │ ││ API │ │ API │ │ API ││Instancia 1│ │Instancia 2│ │Instancia N││ │ │ │ │ │└───────────┘ └───────────┘ └───────────┘ │ │ │ └────────────────┼────────────────┘ │ ▼ ┌───────────────┐ │ │ │ Clúster de │ │ Base de Datos │ │ │ └───────────────┘ │ ▼ ┌───────────────┐ │ │ │ Clúster de │ │ Redis │ │ │ └───────────────┘
Patrones de Diseño
La aplicación utiliza varios patrones de diseño:
- Patrón Repositorio: Abstracción de acceso a datos
- Inyección de Dependencias: Inyección de servicios y repositorios
- Patrón Fábrica: Creación de objetos de dominio
- Patrón Estrategia: Estrategias de autenticación (JWT, clave API)
- Patrón Middleware: Tubería de procesamiento de solicitudes
- Patrón Constructor: Creación de objetos complejos
- Patrón Adaptador: Adaptación de sistemas externos al dominio