## Problem CORS error: "Access-Control-Allow-Origin header contains multiple values" caused by both Nginx and NestJS sending CORS headers. ## Solution - NestJS handles CORS exclusively (main.ts) - Nginx acts as SSL proxy only (no CORS headers) - Updated .env.production.example with HTTPS origins - Created GUIA-CORS-PRODUCCION.md with complete documentation ## Files Changed - .gitignore: Allow .env.*.example files - apps/backend/.gitignore: Allow .env.*.example files - apps/backend/.env.production.example: HTTPS CORS config - apps/frontend/.env.production.example: HTTPS/WSS config - docs/95-guias-desarrollo/GUIA-CORS-PRODUCCION.md: Full guide ## Production Steps 1. Update .env.production files with HTTPS origins 2. Remove CORS headers from Nginx config 3. Rebuild frontend, restart backend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
138 lines
5.3 KiB
Plaintext
138 lines
5.3 KiB
Plaintext
# ============================================================================
|
|
# GAMILIT Backend - Production Environment Variables (EXAMPLE)
|
|
# ============================================================================
|
|
# INSTRUCCIONES:
|
|
# 1. Copiar este archivo a .env.production
|
|
# 2. Reemplazar todos los valores <...> con valores reales
|
|
# 3. Configurar como variables de entorno del sistema (recomendado)
|
|
# O usar archivo .env.production (asegurar permisos restrictivos)
|
|
|
|
# ==================== SERVER ====================
|
|
NODE_ENV=production
|
|
PORT=3006
|
|
API_PREFIX=api
|
|
|
|
# ==================== DATABASE ====================
|
|
# IMPORTANTE: Usar credenciales seguras en producción
|
|
DB_HOST=localhost
|
|
DB_PORT=5432
|
|
DB_NAME=gamilit_platform
|
|
DB_USER=gamilit_user
|
|
DB_PASSWORD=<PASSWORD_SEGURO_AQUI>
|
|
DB_SYNCHRONIZE=false
|
|
DB_LOGGING=false
|
|
|
|
# ==================== JWT ====================
|
|
# IMPORTANTE: NUNCA usar valores de ejemplo en producción
|
|
# Generar secret seguro con: openssl rand -base64 32
|
|
JWT_SECRET=<GENERAR_SECRET_SEGURO_AQUI>
|
|
JWT_EXPIRES_IN=15m
|
|
JWT_REFRESH_EXPIRES_IN=7d
|
|
|
|
# ==================== CORS ====================
|
|
# CRÍTICO: Configurar orígenes permitidos correctamente
|
|
#
|
|
# ============================================================================
|
|
# ADVERTENCIA: HEADERS CORS DUPLICADOS
|
|
# ============================================================================
|
|
# Si usas Nginx como proxy SSL, NO agregar headers CORS en Nginx.
|
|
# NestJS maneja CORS internamente en main.ts.
|
|
# Headers duplicados causan error:
|
|
# "The 'Access-Control-Allow-Origin' header contains multiple values"
|
|
#
|
|
# SOLUCION: Solo NestJS maneja CORS, Nginx solo hace proxy sin headers CORS.
|
|
# Ver: docs/95-guias-desarrollo/GUIA-CORS-PRODUCCION.md
|
|
# ============================================================================
|
|
#
|
|
# Servidor actual: 74.208.126.102
|
|
# Frontend puerto: 3005
|
|
#
|
|
# CONFIGURACION RECOMENDADA CON SSL:
|
|
# Incluye HTTPS y HTTP para compatibilidad durante transición
|
|
CORS_ORIGIN=https://74.208.126.102:3005,https://74.208.126.102,http://74.208.126.102:3005,http://74.208.126.102
|
|
ENABLE_CORS=true
|
|
ENABLE_SWAGGER=false
|
|
|
|
# ==================== LOGGING ====================
|
|
LOG_LEVEL=warn
|
|
LOG_TO_FILE=true
|
|
|
|
# ==================== RATE LIMITING ====================
|
|
RATE_LIMIT_TTL=60
|
|
RATE_LIMIT_MAX=100
|
|
|
|
# ==================== SESSION ====================
|
|
# Generar secret con: openssl rand -base64 32
|
|
SESSION_SECRET=<GENERAR_SECRET_SEGURO_AQUI>
|
|
SESSION_MAX_AGE=86400000
|
|
|
|
# ==================== EMAIL ====================
|
|
# Configurar si se usa envío de emails
|
|
EMAIL_FROM=noreply@gamilit.com
|
|
EMAIL_REPLY_TO=support@gamilit.com
|
|
|
|
# ==================== FRONTEND URL ====================
|
|
# URL del frontend para redirects, links en emails, etc.
|
|
# IMPORTANTE: Usar HTTPS si el servidor tiene SSL configurado
|
|
FRONTEND_URL=https://74.208.126.102:3005
|
|
|
|
# ==================== WEB PUSH NOTIFICATIONS (VAPID) ====================
|
|
# Web Push API nativo - No requiere servicios externos (Firebase, etc.)
|
|
# IMPORTANTE: Generar claves VAPID con el comando:
|
|
# npx web-push generate-vapid-keys
|
|
#
|
|
# VAPID (Voluntary Application Server Identification):
|
|
# - Public Key: Se comparte con el frontend para crear subscripciones
|
|
# - Private Key: Se mantiene secreta en backend para firmar notificaciones
|
|
# - Subject: Email de contacto o URL del sitio (mailto: o https:)
|
|
#
|
|
# Ejemplo de generación:
|
|
# $ npx web-push generate-vapid-keys
|
|
# Public Key: BN4GvZtEZiZuqaaObWga7lEP-S1WCv7L1c...
|
|
# Private Key: aB3cDefGh4IjKlM5nOpQr6StUvWxYz...
|
|
#
|
|
# Compatible con: Chrome, Firefox, Edge, Safari 16.4+
|
|
# NOTA: Si no se configuran, push notifications quedarán deshabilitadas (graceful degradation)
|
|
#
|
|
VAPID_PUBLIC_KEY=<GENERAR_CON_WEB_PUSH_GENERATE_VAPID_KEYS>
|
|
VAPID_PRIVATE_KEY=<GENERAR_CON_WEB_PUSH_GENERATE_VAPID_KEYS>
|
|
VAPID_SUBJECT=mailto:admin@gamilit.com
|
|
|
|
# ==================== OPCIONALES ====================
|
|
# Descomentar y configurar si se usan
|
|
|
|
# Uploads
|
|
# MAX_FILE_SIZE=5242880
|
|
# UPLOAD_DESTINATION=./uploads
|
|
# ALLOWED_MIME_TYPES=image/jpeg,image/png,image/gif,application/pdf
|
|
|
|
# Mantenimiento
|
|
# MAINTENANCE_MODE=false
|
|
|
|
# ============================================================================
|
|
# NOTAS DE SEGURIDAD
|
|
# ============================================================================
|
|
#
|
|
# 1. JWT_SECRET: DEBE ser diferente al de desarrollo, usar 32+ caracteres aleatorios
|
|
# 2. DB_PASSWORD: NUNCA commitear credenciales reales al repositorio
|
|
# 3. SESSION_SECRET: Generar valor único y seguro
|
|
# 4. CORS_ORIGIN: Solo incluir orígenes confiables, NUNCA usar "*"
|
|
# 5. ENABLE_SWAGGER: DEBE estar en false en producción
|
|
# 6. Permisos archivo: chmod 600 .env.production (solo owner puede leer)
|
|
# 7. Logs: Verificar que LOG_TO_FILE no exponga datos sensibles
|
|
#
|
|
# ============================================================================
|
|
# VALIDACIÓN PRE-DEPLOY
|
|
# ============================================================================
|
|
#
|
|
# Antes de deploy, verificar:
|
|
# [ ] JWT_SECRET cambiado de valor de ejemplo
|
|
# [ ] DB_PASSWORD configurado correctamente
|
|
# [ ] CORS_ORIGIN incluye origen del frontend en producción
|
|
# [ ] ENABLE_SWAGGER=false
|
|
# [ ] FRONTEND_URL apunta a URL correcta
|
|
# [ ] Todas las variables <...> reemplazadas
|
|
# [ ] VAPID_* configuradas si se requieren push notifications (generar con npx web-push generate-vapid-keys)
|
|
#
|
|
# ============================================================================
|