← Servidor web y API con Node

Sesión 13 · Semana 5

Configuración, secretos y CORS

Hoy · Hoja de ruta

  1. 1. Aprende: Cómo se configura una aplicación para varios entornos y cómo se abre a otros orígenes.
  2. 2. Haz: Centraliza la configuración y decide tu política de CORS.
  3. 3. Comprueba: La aplicación se niega a arrancar si falta algo imprescindible.

Antes de empezar · 5 minutos, sin apuntes

  1. ¿Qué cambiaría entre tu portátil y un servidor real?
  2. ¿Qué debe pasar si falta una variable obligatoria: arrancar a medias o no arrancar?
  3. ¿Quién debería poder llamar a tu API desde otro dominio?

Toda la configuración, en un módulo

// src/configuracion.js
function obligatoria(nombre) {
  const valor = process.env[nombre];
  if (!valor) {
    console.error(`Falta la variable de entorno ${nombre}`);
    process.exit(1);
  }
  return valor;
}

export const configuracion = {
  puerto: Number(process.env.PUERTO ?? 3000),
  entorno: process.env.NODE_ENV ?? "development",
  rutaDatos: process.env.RUTA_DATOS ?? "./datos/productos.json",
  origenesPermitidos: (process.env.ORIGENES ?? "").split(",").filter(Boolean),
  claveApi: obligatoria("CLAVE_API")
};

Fallar al arrancar es mejor que fallar a las tres horas

Si falta una variable imprescindible, el peor comportamiento posible es arrancar como si nada y romperse cuando alguien use la funcionalidad que la necesitaba: entonces el fallo aparece lejos de su causa.

Comprobarlo todo al arrancar convierte un fallo intermitente en un mensaje claro, antes de que nadie llegue a usar la aplicación.

CORS, desde el otro lado

En la UD4 sufriste CORS como cliente. Ahora decides tú:

app.use((peticion, respuesta, next) => {
  const origen = peticion.headers.origin;
  if (origen && configuracion.origenesPermitidos.includes(origen)) {
    respuesta.setHeader("Access-Control-Allow-Origin", origen);
    respuesta.setHeader("Vary", "Origin");
    respuesta.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE");
    respuesta.setHeader("Access-Control-Allow-Headers", "Content-Type");
  }
  if (peticion.method === "OPTIONS") return respuesta.sendStatus(204);
  next();
});

El comodín como renuncia a la configuración

Poner * permite que cualquier página de internet llame a tu API desde el navegador de sus visitantes. Para una API pública de solo lectura puede ser aceptable; para una que modifica datos, no.

Y recuerda qué es CORS y qué no: una protección del navegador. No impide que alguien llame a tu API con un cliente HTTP. La autorización de verdad es otra cosa, y es lo de mañana.

Tu cliente, servido desde el mismo origen, no necesita nada de esto. Lo configuras para quien venga de fuera.

Tarea 13 · Configurar

  1. Crea el módulo de configuración con valores por defecto y comprobaciones.
  2. Haz que la aplicación se niegue a arrancar si falta una variable obligatoria.
  3. Sustituye todos los valores escritos en el código.
  4. Configura CORS con una lista de orígenes permitidos.
  5. Comprueba desde una página de otro origen que se aplica.
  6. Actualiza .env.example y documenta cada variable en el README.
Objetivo mínimoConfiguración centralizada, comprobada al arrancar y documentada.
Si lo tienesComportamiento distinto por entorno: registro detallado solo en desarrollo.
RetoDemuestra con un cliente HTTP que CORS no protege la API de una llamada directa.

Checkpoint · fin de la sesión 13

  • Ningún valor de configuración vive en el código.
  • La aplicación no arranca si falta algo imprescindible.
  • CORS está configurado con una lista, no con un comodín.
  • Sabes qué protege CORS y qué no.
Ver respuestas

1 · Que el fallo aparezca lejos de su causa, mucho después de arrancar.

2 · Solo el navegador: un cliente HTTP no se ve afectado.

3 · Los orígenes concretos que deben poder llamar desde un navegador.