Marcio Cunha

Por qué CORS bloquea peticiones y cómo configurar el backend

Comprende la política de misma origen de los navegadores y aprende a configurar correctamente las cabeceras HTTP en tu servidor para aceptar peticiones de otros dominios.

Marcio Cunha•6 min
También disponible en:PortuguêsEnglish
Resumen
  • La política de misma origen evita que scripts maliciosos lean datos confidenciales de otras pestañas abiertas.
  • CORS actúa como un puente controlado mediante cabeceras HTTP para autorizar conexiones entre distintos dominios.
  • Las peticiones complejas exigen una verificación previa automática llamada preflight mediante el método OPTIONS.
  • Configurar cabeceras como Access-Control-Allow-Origin requiere precaución para no exponer datos sensibles públicamente.
  • En entornos de desarrollo local, el uso de proxies evita bloqueos molestos sin debilitar la seguridad de la API.

Por qué el navegador bloquea tu API desde otro dominio

Cuando comienzas a desarrollar aplicaciones web separando la interfaz visual del servidor de datos, es muy probable que te encuentres con un error frustrante en la consola del navegador indicando que la petición fue bloqueada por una directiva de seguridad llamada CORS. En la práctica, este mecanismo no existe para molestar al programador, sino para proteger al usuario final contra intrusiones silenciosas. Si esta barrera no existiera, cualquier sitio web malicioso que visitaras podría abrir conexiones en segundo plano con tu banca en línea o tu cuenta de correo personal, robando tus sesiones activas sin que te dieras cuenta.

Para entender el origen del problema, debemos hablar sobre la Política de Misma Origen, conocida en inglés como Same-Origin Policy. Esta regla fundamental de seguridad determina que un script ejecutado en una página solo puede interactuar con recursos que provengan exactamente de la misma procedencia. Para el navegador, dos URLs comparten la misma origen únicamente si coinciden estrictamente en protocolo, puerto y nombre de dominio. Si alojas tu interfaz en https://misitio.com e intentas consultar datos en https://api.misitio.com, el navegador detecta de inmediato esta comunicación como un cruce de fronteras y levanta su escudo protector.

Qué es CORS y cómo opera tras bastidores

El acrónimo CORS significa Cross-Origin Resource Sharing, o Compartimiento de Recursos entre Orígenes Cruzados. Funciona como un acuerdo diplomático entre el navegador web y el servidor. Cuando tu código JavaScript intenta realizar una petición hacia otro dominio, el navegador añade una cabecera especial llamada Origin en la solicitud, revelando de dónde proviene el llamado. El servidor debe responder explícitamente indicando si acepta comunicarse con esa dirección específica. Si el servidor responde positivamente e incluye los permisos correctos, el navegador relaja la regla y entrega los datos al script.

Vale la pena señalar que esta restricción estricta ocurre exclusivamente dentro del entorno del navegador. Si ejecutas exactamente la misma petición utilizando herramientas de línea de comandos como curl, o mediante scripts ejecutados directamente en tu backend, la solicitud funcionará a la perfección ya que dichas herramientas no aplican la Política de Misma Origen. El navegador actúa como un inspector riguroso que revisa la respuesta que viene de fuera para decidir si tu código tiene el derecho legal de leer Su contenido. A menudo, la petición llega al servidor y se ejecuta con éxito, pero el navegador intercepta la respuesta e impide que el script del cliente acceda a ella.

Cómo funcionan las peticiones simples y el temido preflight

No toda petición HTTP sigue el mismo camino al tratarse de la autorización de tráfico. Las llamadas peticiones simples suelen usar métodos básicos como GET o POST, apoyándose únicamente en cabeceras estándar como Accept o Content-Type en formatos tradicionales. En estos escenarios, el navegador envía la solicitud directamente y confía en lo que responda el servidor. Si la respuesta contiene las cabeceras de autorización correctas, todo fluye con normalidad. De lo contrario, el navegador bloquea el acceso a los datos y genera un error en la consola.

Sin embargo, cuando el sistema requiere operaciones más complejas —como enviar datos en formato JSON mediante POST o incluir cabeceras personalizadas de autenticación como tokens de acceso—, el navegador adopta una postura de extrema precaución. Antes de enviar la petición real, activa una comprobación preliminar automática conocida como preflight, utilizando el método HTTP OPTIONS. Este sondeo le pregunta al servidor: "¿Tengo permitido enviar este tipo de petición con estas cabeceras específicas?". Si el servidor responde con los parámetros de permiso adecuados, el navegador finalmente autoriza el envío de la solicitud verdadera, tal como analizamos en nuestra guía sobre cómo resolver errores de CORS en aplicaciones front-end.

Cómo configurar las cabeceras adecuadas en tu servidor

Habilitar peticiones de origen cruzado en tu backend requiere enviar las cabeceras de respuesta HTTP correctas que informan al navegador qué orígenes tienen permiso de acceso. La cabecera más importante es Access-Control-Allow-Origin, que define qué dominios pueden consumir los recursos de la API. Puedes especificar un dominio exacto, como https://misitio.com, o utilizar un asterisco para permitir la entrada a cualquiera. Aunque el asterisco parezca la solución más sencilla para el día a día, conlleva riesgos considerables en entornos de producción que manejan datos sensibles de usuarios autenticados, ya que cualquier sitio en internet podría extraer información de tu API.

Más allá del origen permitido, otras cabeceras fundamentales completan la configuración de seguridad del servidor. La cabecera Access-Control-Allow-Methods especifica qué verbos HTTP están permitidos, tales como GET, POST, PUT y DELETE. Por su parte, Access-Control-Allow-Headers autoriza cabeceras específicas en la solicitud como claves de API y tokens de autorización. Si tu aplicación trabaja con cookies de sesión y credenciales de acceso, también deberás habilitar la cabecera Access-Control-Allow-Credentials con un valor verdadero, teniendo en cuenta que el uso del asterisco genérico queda prohibido por los propios navegadores bajo este esquema.

Buenas prácticas y alternativas para el desarrollo diario

Configurar CORS directamente en el código de la aplicación es una tarea sencilla utilizando librerías consagradas, como el paquete cors en el ecosistema Node.js o middlewares nativos en frameworks de otros lenguajes. Sin embargo, en entornos corporativos o servidores de infraestructura robustos, delegar esta responsabilidad en un proxy inverso o en un firewall perimetral suele ser mucho más ventajoso. Configurar las cabeceras de control de origen directamente en herramientas como Nginx o Caddy garantiza que, aunque la aplicación principal sufra caídas o actualizaciones, la política de seguridad de red permanezca intacta y centralizada.

Durante la fase de desarrollo local, cuando el front-end corre en el puerto 3000 y el backend en el 5000, los desarrolladores suelen tropezar con dolores de cabeza debido a estas restricciones de seguridad. Para evitar contaminar el código de producción con reglas permisivas orientadas únicamente a pruebas, la mejor estrategia consiste en configurar un proxy de desarrollo dentro del empaquetador de código, logrando que el navegador perciba ambas aplicaciones bajo un mismo dominio lógico. De este modo, garantizas un flujo de trabajo fluido, mantienes una seguridad estricta en producción y aprendes a gestionar el tráfico de red sin recurrir a soluciones improvisadas. Para complementar esta implementación en entornos de producción, consulte también nuestros análisis técnicos sobre Cómo probar optoacopladores en placa con el multímetro y Cómo usar curl para probar APIs y headers HTTP en la práctica.

Conclusión

Comprender el funcionamiento de CORS y de la Política de Misma Origen es un paso obligatorio para cualquier desarrollador que aspire a construir sistemas web seguros, escalables y bien estructurados. En lugar de percibir estas barreras como un obstáculo molesto, debemos verlas como nuestra primera línea de defensa contra ataques de falsificación y suplantación de sesiones en el ecosistema de los navegadores.

Dominando la configuración correcta de las cabeceras HTTP, manejando adecuadamente las solicitudes preflight y utilizando proxies inteligentes durante el desarrollo, garantizas que tu API funcione de manera fluida y protegida. Al final, alinear una arquitectura de backend robusta con prácticas de red sólidas es el secreto para entregar aplicaciones confiables y libres de vulnerabilidades silenciosas.