Marcio Cunha

Por qué CORS bloquea peticiones y cómo configurar en Node

Comprende los fundamentos de la Same-Origin Policy y aprende a configurar cabeceras Access-Control-Allow-Origin en Node.js para eliminar errores de CORS.

Marcio Cunha•5 min
También disponible en:PortuguêsEnglish
Resumen
  • La Same-Origin Policy aísla contextos de navegación para impedir que scripts maliciosos roben datos entre diferentes orígenes.
  • El navegador envía una petición de prueba preflight usando el método OPTIONS antes de ejecutar llamadas complejas al backend.
  • La cabecera Access-Control-Allow-Origin autoriza dominios específicos o cualquier origen a leer la respuesta de los recursos proporcionados.
  • El ecosistema Node.js simplifica esta seguridad mediante bibliotecas dedicadas que inyectan las cabeceras HTTP necesarias automáticamente.
  • Configuraciones adicionales como credentials exigen ajustes estrictos para permitir el envío seguro de cookies y tokens de autenticación.

Qué es CORS y por qué existe en la web moderna

Quien programa para la web inevitablemente se ha topado con ese mensaje rojo en la consola del navegador indicando que una petición fue bloqueada debido a CORS. Este mecanismo de seguridad suele generar frustración inicial en desarrolladores que intentan conectar una aplicación frontend a un servidor backend alojado en otra dirección. Sin embargo, lejos de ser un mero obstáculo, CORS cumple un papel fundamental para mantener la integridad de los datos y la privacidad de los usuarios en un ecosistema digital altamente conectado.

Para entender el bloqueo, debemos dar un paso atrás y observar la directriz básica que rige la navegación: la Same-Origin Policy, o política del mismo origen. En términos prácticos, esta regla determina que un script ejecutado en una página web solo puede interactuar con recursos que provengan exactamente del mismo protocolo, dominio y puerto. Si tu sitio se ejecuta en https://misitio.com, no puede leer datos de https://api.otrositio.com por defecto, ya que el navegador asume que el segundo sitio podría ser malicioso e intentar robar información sensible de la sesión del usuario.

Aquí es donde entra CORS, sigla en inglés para Intercambio de Recursos de Origen Cruzado. Funciona como una especie de aduana inteligente para el navegador. Cuando una aplicación intenta sortear la política del mismo origen mediante peticiones asíncronas, CORS actúa para permitir que el servidor autorice explícitamente qué orígenes externos tienen permiso para acceder a los datos proporcionados. Para profundizar en la comunicación de servidores y redes, vale la pena revisar las pautas del artículo sobre por qué CORS bloquea peticiones y cómo configurar el backend.

Cómo funcionan la verificación previa y el método OPTIONS en la práctica

Muchos programadores se sorprenden al descubrir que el navegador realiza más de una llamada al servidor cuando realizamos peticiones que modifican datos o utilizan cabeceras personalizadas. Este proceso involucra la llamada conocida como preflight, una petición de prueba enviada automáticamente por el navegador antes de la petición real. El objetivo es verificar si el servidor remoto acepta los parámetros de la comunicación que está a punto de suceder.

En la práctica, esta petición preliminar utiliza el método HTTP llamado OPTIONS. El navegador pregunta al servidor cuáles son las reglas vigentes, enviando cabeceras que informan qué método real se utilizará y qué credenciales o parámetros extra acompañarán la carga útil. Si el servidor responde positivamente con los permisos correctos, el navegador autoriza que la petición principal siga su curso. De lo contrario, el bloqueo se activa y ningún dato sensible llega al frontend.

Este comportamiento nos muestra que CORS es, principalmente, una restricción impuesta por el lado del cliente, es decir, por el propio navegador. Si realizas exactamente la misma petición utilizando herramientas de línea de comandos como curl o scripts de servidores backend, el bloqueo no ocurrirá porque esas herramientas no implementan la Same-Origin Policy. Comprender esta distinción evita la falsa impresión de que la API está fallando cuando, en realidad, el navegador solo está cumpliendo su papel de guardaespaldas digital del usuario.

Cómo configurar CORS correctamente en una aplicación Node.js

Cuando desarrollamos APIs utilizando el ecosistema Node.js con frameworks populares como Express, necesitamos orientar explícitamente al servidor a responder a los navegadores con las cabeceras de permiso correctas. La cabecera más importante en esta estructura es Access-Control-Allow-Origin, que define quién tiene el derecho de leer la respuesta generada por la aplicación.

La forma más elegante y segura de gestionar esto en Node.js es utilizando el paquete oficial de middleware de CORS. En vez de escribir manualmente líneas de código para inyectar cabeceras en cada respuesta HTTP, la biblioteca gestiona tanto las peticiones normales como las llamadas de prueba OPTIONS de forma centralizada y sin complicaciones.

const express = require('express');
const cors = require('cors');
const app = express();

const corsOptions = {
  origin: 'https://mifrontend.com',
  optionsSuccessStatus: 200
};

app.use(cors(corsOptions));

app.get('/api/datos', (req, res) => {
  res.json({ mensaje: '¡Acceso permitido con éxito!' });
});

app.listen(3000, () => {
  console.log('Servidor corriendo en el puerto 3000');
});

En el fragmento de código anterior, configuramos la aplicación para aceptar peticiones estrictamente provenientes de https://mifrontend.com. Si cualquier otro sitio intenta consumir esta ruta usando un navegador, la respuesta será bloqueada por las reglas del cliente. Para escenarios de desarrollo local, es común permitir múltiples dominios o incluso liberar temporalmente todos los orígenes usando el carácter comodín *, aunque esta práctica debe evitarse en entornos de producción por cuestiones de seguridad.

Precauciones esenciales al tratar con credenciales y cabeceras personalizadas

Otorgar acceso genérico a cualquier dominio suele ser suficiente para APIs públicas, pero el escenario cambia drásticamente cuando necesitamos autenticar usuarios. Si tu aplicación utiliza cookies seguras, tokens de sesión o cabeceras de autorización personalizadas, el comportamiento estándar de CORS exige configuraciones adicionales rigurosas tanto en el cliente como en el servidor.

Cuando habilitamos el envío de credenciales mediante la propiedad credentials: true en el fetch del frontend, el servidor Node.js deja de aceptar el carácter comodín * en la cabecera de origen. La respuesta del servidor debe especificar obligatoriamente el dominio exacto autorizado para realizar la operación. Este requisito evita que sitios maliciosos puedan extraer datos de sesiones autenticadas sin el consentimiento explícito del administrador de la API.

Además del origen y las credenciales, vale la pena monitorear el uso de cabeceras personalizadas. Si tu frontend necesita enviar un token de autenticación propietario en una cabecera llamada X-Custom-Token, el servidor Node.js debe listar explícitamente ese nombre en la configuración de CORS a través del parámetro correspondiente, asegurando que el navegador no intercepte y descarte la comunicación durante la fase de validación previa. Para complementar esta implementación en entornos de producción, consulte también nuestros análisis técnicos sobre Cómo probar una fuente ATX de PC con un clip de papel y Cómo diagnosticar pérdida de paquetes en la red usando el comando ping.

Consideraciones finales sobre seguridad y arquitectura de APIs

El dominio del mecanismo CORS es una competencia indispensable para cualquier desarrollador que trabaje en desarrollo web full-stack. Comprender que el bloqueo no representa un defecto del código, sino una capa de protección arquitectónica impuesta por los navegadores, cambia por completo la forma en que encaramos los errores de integración entre frontend y backend.

Al configurar tu servidor Node.js con políticas restrictivas y adecuadas al entorno de producción, garantizas que tu aplicación permanezca accesible para los clientes legítimos mientras bloqueas intentos no deseados de exploración. Mantener estas directrices bien ajustadas evita fallas de seguridad silenciosas y fortalece la solidez de toda la infraestructura digital de tu organización.