s3-back-dtb
v1.0.0
Published
API de almacenamiento de archivos tipo S3 - Backend ejecutable
Readme
s3-back-dtb
API de almacenamiento de archivos tipo S3. Paquete npm ejecutable para instalar en un servidor.
Configuración
Variables de Entorno
El backend NO usa config.json. Toda la configuración se hace mediante variables de entorno.
Variables Requeridas
| Variable | Descripción | Ejemplo |
|----------|-------------|---------|
| CLIENT_SECRET | Clave secreta compartida con los clientes para firmar tokens (mínimo 32 caracteres) | CLIENT_SECRET=mi-clave-secreta-compartida-minimo-32-caracteres |
| TOTP_SECRET | Semilla TOTP compartida con los clientes (mínimo 16 caracteres) | TOTP_SECRET=mi-semilla-totp-compartida-minimo-16-caracteres |
Variables Opcionales
| Variable | Descripción | Default | Ejemplo |
|----------|-------------|---------|---------|
| PORT | Puerto del servidor HTTP | 3000 | PORT=4000 |
| STORAGE_ROOT_PATH | Ruta donde se guardan los archivos | ./uploads | STORAGE_ROOT_PATH=/var/storage |
| MAX_FILE_SIZE | Tamaño máximo de archivo | 50mb | MAX_FILE_SIZE=100mb |
| ALLOWED_MIME_TYPES | Tipos MIME permitidos (separados por coma) | * | ALLOWED_MIME_TYPES=image/*,video/*,application/pdf |
| TOKEN_EXPIRES_IN | Duración de los tokens JWT generados por los clientes | 5m | TOKEN_EXPIRES_IN=1h |
| TOTP_PERIOD | Duración del período TOTP en segundos (15–300). Debe coincidir con STORAGE_TOTP_PERIOD en clientes | 30 | TOTP_PERIOD=60 |
| CORS_ORIGINS | Orígenes permitidos (separados por coma) | * | CORS_ORIGINS=https://miapp.com,http://localhost:3000 |
| CORS_METHODS | Métodos HTTP permitidos (separados por coma) | GET,POST,PUT,DELETE,HEAD,OPTIONS | CORS_METHODS=GET,POST,DELETE |
| TRUST_PROXY | Habilitar si está detrás de proxy | false | TRUST_PROXY=true |
| REQUEST_TIMEOUT | Timeout de peticiones en ms | 30000 | REQUEST_TIMEOUT=60000 |
| NODE_ENV | Entorno de ejecución | development | NODE_ENV=production |
Notas:
- El tiempo de expiración (
TOKEN_EXPIRES_IN) puede ser sobrescrito por el cliente en su.envconSTORAGE_TOKEN_EXPIRES_IN. - El período TOTP (
TOTP_PERIOD) debe coincidir conSTORAGE_TOTP_PERIODen cada cliente; si difieren, la autenticación fallará.
Validación de Variables de Entorno
El backend valida automáticamente todas las variables de entorno usando Joi. Si falta alguna variable requerida o tiene un formato inválido, el servidor no iniciará y mostrará un error descriptivo.
Ejemplo de error de validación:
Error de validación de variables de entorno: CLIENT_SECRET es requerido como variable de entorno, TOTP_SECRET debe tener al menos 16 caracteres por seguridadInstalación
npm install s3-back-dtbO globalmente:
npm install -g s3-back-dtbEjecución
Opción 1: Con npx (instalación local)
CLIENT_SECRET=tu-clave-secreta-compartida TOTP_SECRET=tu-semilla-totp-compartida npx s3-back-dtbOpción 2: Comando global
npm install -g s3-back-dtb
CLIENT_SECRET=tu-clave-secreta TOTP_SECRET=tu-semilla-totp s3-back-dtbOpción 3: Con archivo .env (Recomendado)
El servidor carga automáticamente variables de entorno desde un archivo .env usando dotenv.
Paso 1: Generar secrets seguros
# Desde el directorio del proyecto (s3-package)
npm run generate:secretsEsto generará dos secrets aleatorios. Copia y pega los valores en tu archivo .env.
Paso 2: Crear archivo .env
Copia el archivo de ejemplo y edítalo:
cp .env.example .envLuego edita .env y pega los secrets generados:
CLIENT_SECRET=tu-clave-secreta-generada-minimo-32-caracteres
TOTP_SECRET=tu-semilla-totp-generada-minimo-16-caracteres
PORT=3000
STORAGE_ROOT_PATH=./uploads
TOKEN_EXPIRES_IN=5m
TOTP_PERIOD=30IMPORTANTE: Los valores CLIENT_SECRET y TOTP_SECRET deben estar en el .env de cada cliente como STORAGE_CLIENT_SECRET y STORAGE_TOTP_SECRET. Si usas TOTP_PERIOD distinto de 30, configura también STORAGE_TOTP_PERIOD en los clientes con el mismo valor.
Paso 3: Ejecutar
npx s3-back-dtbEl servidor cargará automáticamente las variables desde .env.
Opción 4: En producción con PM2
# Instalar PM2
npm install -g pm2
# Crear archivo .env con las variables
cat > .env << EOF
CLIENT_SECRET=tu-clave-secreta-compartida-minimo-32-caracteres
TOTP_SECRET=tu-semilla-totp-compartida-minimo-16-caracteres
PORT=3000
STORAGE_ROOT_PATH=/var/storage
TOKEN_EXPIRES_IN=5m
NODE_ENV=production
EOF
# Iniciar el servidor
pm2 start s3-back-dtb --name "s3-api" --env .env
# Ver logs
pm2 logs s3-api
# Reiniciar
pm2 restart s3-api🔗 Integración con Cliente
Para que los clientes puedan conectarse a este backend, necesitas compartir ciertos valores de configuración.
Configuración Compartida
El backend y los clientes deben compartir los siguientes valores:
| Variable del Backend | Variable del Cliente | Descripción |
|---------------------|---------------------|-------------|
| CLIENT_SECRET | STORAGE_CLIENT_SECRET | Clave secreta para firmar tokens (mínimo 32 caracteres) |
| TOTP_SECRET | STORAGE_TOTP_SECRET | Semilla TOTP para generar códigos (mínimo 16 caracteres) |
| TOTP_PERIOD | STORAGE_TOTP_PERIOD | Período TOTP en segundos (15-300, default: 30) |
⚠️ IMPORTANTE: Estos valores deben ser exactamente iguales en ambos lados. Si difieren, la autenticación fallará.
Flujo de Configuración Completo
Paso 1: Configurar el Backend
Genera secrets seguros:
cd s3-package npm run generate:secretsCopia los valores generados a tu
.env:CLIENT_SECRET=tu-clave-secreta-generada-minimo-32-caracteres TOTP_SECRET=tu-semilla-totp-generada-minimo-16-caracteres TOTP_PERIOD=30 PORT=3000Inicia el servidor:
npm run start:dev
Paso 2: Configurar el Cliente
En tu aplicación cliente, crea un archivo .env con:
# Identificación del cliente
STORAGE_CLIENT_ID=mi-cliente-123
STORAGE_CLIENT_NAME=Mi Aplicacion
# URL del backend (debe coincidir con el puerto configurado)
STORAGE_BASE_URL=http://localhost:3000
# Permisos del cliente
STORAGE_PERMISSIONS=["read","write","delete"]
# Rutas permitidas (usa "*" para todas)
STORAGE_ALLOWED_PATHS=["*"]
# ⚠️ IMPORTANTE: Estos valores DEBEN coincidir con el backend
STORAGE_CLIENT_SECRET=tu-clave-secreta-generada-minimo-32-caracteres
STORAGE_TOTP_SECRET=tu-semilla-totp-generada-minimo-16-caracteres
STORAGE_TOTP_PERIOD=30Paso 3: Verificar la Conexión
En tu código cliente:
import 'dotenv/config';
import { createClientFromConfig } from 's3-client-dtb';
const client = createClientFromConfig();
// Verificar que la configuración es correcta
try {
await client.verifyTotp();
console.log('✅ Cliente conectado correctamente al backend');
} catch (error) {
console.error('❌ Error de conexión:', error);
// Verifica que los secrets coincidan y que el servidor esté corriendo
}Ejemplo Completo de Configuración
Backend (.env):
CLIENT_SECRET=abc123def456ghi789jkl012mno345pqr678stu901vwx234yz
TOTP_SECRET=ABCDEFGHIJKLMNOP
TOTP_PERIOD=30
PORT=3000
STORAGE_ROOT_PATH=./uploads
TOKEN_EXPIRES_IN=5mCliente (.env):
STORAGE_CLIENT_ID=mi-app-prod
STORAGE_CLIENT_NAME=Mi Aplicacion de Produccion
STORAGE_BASE_URL=http://localhost:3000
STORAGE_PERMISSIONS=["read","write","delete"]
STORAGE_ALLOWED_PATHS=["*"]
STORAGE_CLIENT_SECRET=abc123def456ghi789jkl012mno345pqr678stu901vwx234yz
STORAGE_TOTP_SECRET=ABCDEFGHIJKLMNOP
STORAGE_TOTP_PERIOD=30
STORAGE_TOKEN_EXPIRES_IN=5mSolución de Problemas
El cliente no puede autenticarse:
- Verifica que
STORAGE_CLIENT_SECRET=CLIENT_SECRET(exactamente igual) - Verifica que
STORAGE_TOTP_SECRET=TOTP_SECRET(exactamente igual) - Verifica que
STORAGE_TOTP_PERIOD=TOTP_PERIOD(si no es 30) - Asegúrate de que el servidor esté corriendo y accesible
Error de timeout:
- Verifica que
STORAGE_BASE_URLapunte a la URL correcta del servidor - Verifica que el servidor esté corriendo en el puerto configurado
- Verifica la conectividad de red
Error 403 Forbidden:
- Verifica que los permisos del cliente (
STORAGE_PERMISSIONS) incluyan la operación que intentas realizar - Verifica que
STORAGE_ALLOWED_PATHSpermita la ruta que intentas usar
Autenticación con JWT y TOTP
El sistema usa autenticación basada en JWT con TOTP (Time-based One-Time Password). Cada cliente configura su conexión mediante variables de entorno (.env) con su configuración (clientId, permisos, paths, tiempos de expiración, y las claves compartidas).
Flujo de Autenticación
- Cliente genera token: El cliente genera un código TOTP usando la semilla compartida (
TOTP_SECRET) - Cliente firma token: El cliente genera un token JWT usando
CLIENT_SECRET + TOTP_CODEcomo secreto - Cliente envía token: El cliente envía el token en el header
Authorization: Bearer <token> - Servidor valida: El servidor genera el mismo código TOTP y valida el token usando
CLIENT_SECRET + TOTP_CODE - Acceso autorizado: Si el token es válido, el servidor permite el acceso según los permisos del payload
Cómo Funciona
Cliente y servidor comparten:
CLIENT_SECRET: Clave secreta para firmar tokensTOTP_SECRET: Semilla para generar códigos TOTP
TOTP (Time-based OTP):
- Código que cambia cada 30 segundos
- Ambos (cliente y servidor) generan el mismo código usando la misma semilla y tiempo
- Proporciona seguridad adicional ya que el secreto de firma cambia constantemente
Token JWT:
- Contiene:
clientId,permissions,allowedPaths - Firmado con:
CLIENT_SECRET + TOTP_CODE - Tiempo de expiración configurable (default: 5 minutos)
- Contiene:
Endpoints de Autenticación
Verificar TOTP (Opcional - para validar configuración)
POST /apifiles/auth/otp/verify
Content-Type: application/json
{
"clientId": "mi-cliente-123",
"otp": "123456"
}
Response:
{
"success": true,
"data": {
"message": "TOTP verificado correctamente. Puedes generar tokens ahora."
}
}Este endpoint es opcional y se usa para verificar que el cliente puede generar códigos TOTP correctos. Una vez verificado, el cliente puede generar tokens directamente sin necesidad de este endpoint.
Endpoints de la API
Base URL: http://localhost:PORT/apifiles
IMPORTANTE: Todas las peticiones requieren el token JWT:
Authorization: Bearer <token>
Subir archivo
POST /apifiles/files
Content-Type: multipart/form-data
Authorization: Bearer <token>
Body:
- file: (archivo)
- filePath: "images" (subdirectorio)Descargar archivo
GET /apifiles/files/{path}
Authorization: Bearer <token>Listar archivos
GET /apifiles/files?directory=images&limit=50&offset=0
Authorization: Bearer <token>Eliminar archivo
DELETE /apifiles/files/{path}
Authorization: Bearer <token>Metadata de archivo (HEAD)
HEAD /apifiles/files/{path}
Authorization: Bearer <token>Health check
GET /apifiles/healthDocumentación Swagger
Disponible en: http://localhost:PORT/apifiles/docs
Seguridad
Características de Seguridad
- TOTP (Time-based OTP): Código que cambia cada 30 segundos, proporcionando seguridad dinámica
- Token JWT con firma dinámica: El secreto de firma es
CLIENT_SECRET + TOTP_CODE, cambiando cada 30 segundos - Tiempo de expiración configurable: Los tokens expiran según
tokenExpiresIn(default: 5 minutos) - Claves compartidas:
CLIENT_SECRETyTOTP_SECRETcompartidas entre cliente y servidor - Validación de ventana de tiempo: El servidor acepta tokens generados con TOTP de períodos adyacentes (±30 segundos) para compensar diferencias de reloj
- Sin almacenamiento de estado: El servidor no almacena tokens, solo valida la firma
- Validación de permisos: Cada cliente tiene permisos específicos (read, write, delete)
- Validación de paths: Cada cliente solo puede acceder a paths permitidos
- Rate limiting: Configurable por cliente
- HTTPS recomendado: En producción, usar HTTPS para proteger tokens en tránsito
Mejores Prácticas
- Usa secrets fuertes y únicos en producción:
CLIENT_SECRET: mínimo 32 caracteresTOTP_SECRET: mínimo 16 caracteres
- Almacena secrets en variables de entorno, nunca en código
- IMPORTANTE: Los mismos valores de
CLIENT_SECRETyTOTP_SECRETdeben estar en el servidor (comoCLIENT_SECRETyTOTP_SECRET) y en el archivo.envde cada cliente (comoSTORAGE_CLIENT_SECRETySTORAGE_TOTP_SECRET) - Configura CORS apropiadamente para tu dominio
- Monitorea intentos de autenticación fallidos
- Usa HTTPS en producción
- Sincroniza relojes: El TOTP depende del tiempo, asegúrate de que cliente y servidor tengan relojes sincronizados
Ejemplo Completo
Instalar:
npm install s3-back-dtbConfigurar variables de entorno:
Opción A: Con archivo .env (Recomendado)
# Generar secrets seguros npm run generate:secrets # Copiar ejemplo y editar cp .env.example .env # Pegar los secrets generados en .envOpción B: Variables de entorno directas
export CLIENT_SECRET=tu-clave-secreta-compartida-minimo-32-caracteres export TOTP_SECRET=tu-semilla-totp-compartida-minimo-16-caracteres export PORT=3000 export STORAGE_ROOT_PATH=./uploads export TOKEN_EXPIRES_IN=5mEjecutar:
npx s3-back-dtbEl cliente se conecta: El cliente debe tener su propio archivo
.envcon su configuración (ver documentación del cliente enpackage-npm/README.md). El cliente genera tokens automáticamente usando las claves compartidas.
Arquitectura
Backend (s3-package)
- Sin config.json: Todo se configura por variables de entorno
- Validación con Joi: Todas las variables se validan al iniciar
- Sin lista de clientes: Los clientes se autentican enviando su configuración
Cliente (package-npm)
- Con variables de entorno (.env): Cada cliente tiene su propio archivo
.envcon su configuración - Configuración completa: Incluye clientId, permisos, paths, rateLimit y tiempos de expiración mediante variables de entorno
- Autenticación automática: El cliente genera tokens automáticamente usando TOTP y maneja la renovación automáticamente
Licencia
MIT
