# GUIA-CORS-PRODUCCION.md ## Configuración CORS para Producción - GAMILIT **Fecha**: 2025-12-18 **Problema resuelto**: Error `Access-Control-Allow-Origin contains multiple values` --- ## 1. Descripción del Problema Al hacer requests desde el frontend (puerto 3005) al backend (puerto 3006) en producción con HTTPS, se recibe el error: ``` Access to XMLHttpRequest at 'https://74.208.126.102:3006/api/v1/auth/register' from origin 'https://74.208.126.102:3005' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'https://74.208.126.102:3005, https://74.208.126.102:3005', but only one is allowed. ``` --- ## 2. Causa Raíz El header `Access-Control-Allow-Origin` se está enviando **DOS VECES**: 1. **Nginx** (proxy SSL) agrega headers CORS 2. **NestJS** (backend) también agrega headers CORS via `app.enableCors()` Cuando ambos envían el header, el navegador ve valores duplicados y rechaza la respuesta. --- ## 3. Solución Definitiva ### Regla de Oro: **Solo NestJS maneja CORS** Nginx debe actuar únicamente como proxy SSL sin agregar headers CORS. ### 3.1 Configuración Backend (.env.production) ```bash # CORS - CONFIGURACIÓN CRÍTICA # ============================================================================ # 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" # ============================================================================ # 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 ``` ### 3.2 Configuración Frontend (.env.production) ```bash # SSL CONFIGURADO - Usar HTTPS/WSS VITE_API_HOST=74.208.126.102:3006 VITE_API_PROTOCOL=https VITE_WS_HOST=74.208.126.102:3006 VITE_WS_PROTOCOL=wss ``` ### 3.3 Configuración Nginx (SIN CORS) ```nginx # /etc/nginx/sites-available/gamilit-backend server { listen 3006 ssl; server_name 74.208.126.102; ssl_certificate /etc/ssl/certs/gamilit.crt; ssl_certificate_key /etc/ssl/private/gamilit.key; location / { proxy_pass http://127.0.0.1:3007; # PM2 cluster interno proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; # ⚠️ NO AGREGAR headers CORS aquí # NestJS los maneja internamente } } ``` --- ## 4. Verificación ### 4.1 Verificar headers con curl ```bash # Verificar que solo hay UN header Access-Control-Allow-Origin curl -I -X OPTIONS \ -H "Origin: https://74.208.126.102:3005" \ -H "Access-Control-Request-Method: POST" \ https://74.208.126.102:3006/api/v1/auth/register # Salida esperada (UN solo header): # Access-Control-Allow-Origin: https://74.208.126.102:3005 # Access-Control-Allow-Credentials: true # Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS ``` ### 4.2 Verificar configuración Nginx ```bash # Buscar headers CORS duplicados en configuración grep -r "Access-Control" /etc/nginx/ ``` Si encuentra líneas como `add_header Access-Control-Allow-Origin`, elimínelas. --- ## 5. Pasos de Deploy 1. **Backend**: Actualizar `.env.production` con HTTPS origins 2. **Frontend**: Actualizar `.env.production` con HTTPS/WSS 3. **Nginx**: Remover cualquier header CORS 4. **Reiniciar servicios**: ```bash sudo systemctl reload nginx pm2 restart gamilit-backend cd /path/to/frontend && npm run build ``` --- ## 6. Troubleshooting ### Error persiste después de la configuración 1. Verificar que Nginx no tenga headers CORS en ningún include 2. Revisar si hay otro proxy (CloudFlare, etc.) agregando headers 3. Limpiar cache del navegador (F12 > Network > Disable cache) ### Error "CORS blocked request" en logs - El origen que hace la petición no está en CORS_ORIGIN - Verificar que el protocolo coincide (https vs http) --- ## 7. Referencias - **Backend CORS**: `apps/backend/src/main.ts` líneas 27-46 - **Config CORS**: `apps/backend/src/config/app.config.ts` - **Ejemplo .env**: `apps/backend/.env.production.example`