¿Se pregunta qué es CORS (Cross-Origin Resource Sharing)?

En las películas de espías, los agentes de seguridad tienen una forma codificada de transmitir información entre ellos. Dado que en la mayoría de los casos transmiten información que puede ser utilizada en su contra si cae en manos de sus enemigos, tienen que asegurarse de que quienes reciben la información son personas de confianza. Lo mismo se aplica a los que están enviando dicha información. Cuando el emisor y el receptor son de confianza, se puede garantizar la credibilidad y la seguridad de la información.

https://pt.slideshare.net/atirekgupta/selenium-workshop-34820044

Una réplica de este escenario se da en la comunicación entre navegadores y servidores web, y se denomina política del mismo origen.

¿Qué es la política del mismo origen?

¿Se ha dado cuenta alguna vez de que las páginas web no pueden acceder a recursos de un sitio web diferente? Eso se debe a la política del mismo origen, que es una función de seguridad de los navegadores web que impide que las páginas web accedan a recursos (como cookies, scripts y otros datos) de un dominio diferente al que sirvió la página.

Un origen se define por la combinación del protocolo, el dominio y el número de puerto de una URL. La mayoría de los navegadores, incluidos Chrome, Firefox, Safari y Edge, aplican una política de mismo origen para mantener sus datos a salvo.

Same-Origin-Policy

Ahora bien, ¿por qué necesitamos esta política? Para entenderlo, echemos un vistazo a cómo funciona Internet. Usted visita un sitio web, su navegador envía una solicitud al servidor que aloja ese sitio web, y el servidor responde enviando de vuelta los recursos necesarios para mostrar la página. Estos recursos pueden incluir HTML, CSS, JavaScript e imágenes.

Imagine que una página web también pudiera hacer peticiones a otros dominios. Para continuar con nuestra premisa de película de espías, un agente secreto de otra agencia quiere ponerse en contacto con un agente de una organización o país diferente, solicitar acceso y compartir información. Si se les concede esta oportunidad, se abre a la organización posterior a enormes vulnerabilidades de seguridad. Pueden robar información sensible y perjudicarles potencialmente.

La política del mismo origen existe precisamente para atajar este problema. Aunque hay algunos malentendidos sobre la SOP, no significa que no se puedan cargar recursos de distintos orígenes o enviar información a otro origen.

Sin embargo, la SOP establece reglas que limitan el acceso y la interacción entre diferentes recursos, como scripts, CSS, iframes, imágenes y vídeos. Es como un guardián que mantiene las páginas web en su propio dominio y les impide acceder a recursos de otros dominios.

Esto le mantiene a salvo de ataques maliciosos que podrían robar sus datos o engañarle para que realice acciones no deseadas.

¿Qué es CORS?

En un caso de la vida real, cuando los agentes de seguridad dan una norma para que la comunicación sólo se produzca entre sus agentes como medio de seguridad, eso es similar a la política del mismo origen. Sin embargo, puede haber casos en los que necesiten interactuar con el mundo exterior. O con operativos de otros conjuntos de seguridad, para que eso ocurra, pueden implementar otra medida de seguridad para verificar a esos operativos. Esta verificación puede darse de diferentes maneras, dependiendo de los operativos implicados. En el caso de la comunicación en Internet, CORS es el mecanismo que hace posible que los navegadores utilicen para acceder a recursos a los que originalmente no podrían porque el recurso es de un origen diferente.

La compartición de recursos entre orígenes (CORS) es un mecanismo que utiliza cabeceras HTTP adicionales para indicar a los navegadores que den a una aplicación web que se ejecuta en un origen, acceso a recursos seleccionados de un origen diferente.

He hablado del origen más de una vez y probablemente se pregunte qué significa. Un origen se define por el protocolo, el dominio y el puerto de la URL. Cuando tiene su API en un origen como https://api.geekflare.com/es:3001 y su frontend en https://geekflare.com/es, se dice que los orígenes son diferentes. En esta situación, necesitará CORS para poder acceder a los recursos en ambos extremos.

Cuando se realizan peticiones a un servidor, los navegadores (cliente) y los servidores envían peticiones y respuestas, se incluyen cabeceras HTTP. Entre estas cabeceras, se incluyen otras adicionales para evitar que el navegador bloquee la comunicación.

¿Por qué el navegador bloqueará la comunicación?

Por las funciones de seguridad de su navegador. Lo hará si la solicitud procede de un origen distinto al del cliente. Las cabeceras adicionales incluidas como resultado de CORS es una forma de decirle al cliente que puede hacer uso de la respuesta que ha recibido.

Problemas comunes con CORS

Como desarrollador web, usted necesita acceder a recursos de diferentes dominios – como cuando construye una aplicación web que utiliza APIsde múltiples fuentes. Usted implementa CORS, que permite a los servidores web especificar a qué otros dominios se les permite acceder a sus recursos, para que pueda seguir construyendo las aplicaciones web que desea. Este comportamiento se implementa en el lado del servidor, por lo que no puede reconfigurarse en el lado del cliente.

Si se encuentra con un error CORS, significa que el servidor ha denegado su solicitud para acceder a sus recursos desde un dominio diferente porque no cumple las normas de seguridad requeridas.

Esto puede ocurrir si el servidor no dispone de la configuración adecuada. Pero no se preocupe: hay una forma fácil de solucionarlo. Sólo tiene que asegurarse de que la cabecera Access-Control-Allow-Origin está correctamente configurada. Esto indica al servidor qué dominios tienen permiso para acceder a sus recursos, por lo que si no está configurado correctamente, puede encontrarse con problemas.

Cross-Origin-Resource-Sharing-Issues

He aquí otros problemas con los que puede encontrarse:

  • Si intenta utilizar un método HTTP no simple (como DELETE o PUT) en una solicitud de intercambio de recursos entre orígenes, es importante que se asegure de que el servidor lo permite. Los navegadores sólo permiten métodos simples por defecto, por lo que tendrá que establecer explícitamente la cabecera Access-Control-Allow-Methods si desea utilizar un método diferente.
  • Además, al realizar este tipo de peticiones, deberá tener cuidado con el envío de credenciales (como cookies o cabeceras de autorización) desde el navegador que el servidor permita.
  • Además, el servidor no responderá correctamente si la consulta «preflight» para una solicitud no simple (como una con cabeceras personalizadas) revela que no está soportada.
  • Si una página web intenta acceder a recursos (alojados en una red de distribución de contenidos) como imágenes, scripts u hojas de estilo de un dominio diferente, es posible que el servidor que aloja el recurso no permita solicitudes del dominio en el que está alojada la página.

Por suerte, existen algunas formas de resolver este problema. Una solución es configurar el servidor para que permita las peticiones de origen cruzado enviando las cabeceras adecuadas.

Otra opción es utilizar un servidor proxy para realizar la solicitud en nombre de su aplicación web o utilizar JSON-P para envolver la respuesta en una función de devolución de llamada.

Además, existen bibliotecas que simplifican las solicitudes de origen cruzado en el lado del cliente gestionando las cabeceras y proporcionando una API de solicitud sin problemas.

Probando estas diferentes soluciones, puede sortear estos problemas y asegurarse de que su aplicación web puede acceder a los recursos que necesita para funcionar correctamente.

Una advertencia: estas técnicas pueden conllevar sus propios riesgos de seguridad, por lo que es importante utilizarlas con cuidado

Cabeceras CORS

Una de las cabeceras seguras que puede ser de respuesta o de solicitud.

Cabeceras de respuesta

Son las cabeceras que el servidor devuelve en su respuesta.

  • Access-Control-Allow-Origin: <origen>: Se utiliza para especificar el origen permitido para acceder al recurso en el servidor. Es posible especificar que sólo se permitan solicitudes de un origen concreto – Access-Control-Allow-Origin: https://geekflare.com/es, o que el origen no importe – Access-Control-Allow-Origin:*.
  • Access-Control-Expose-Headers: <headers>: Como su nombre indica, enumera las cabeceras a las que tiene acceso el navegador.
  • Access-Control-Max-Age: <segundos>: Indica la duración durante la cual se puede almacenar en caché la respuesta de una solicitud de verificación previa.
  • Access-Control-Allow-Credentials: <boolean>: Indica que el navegador puede hacer uso de la respuesta cuando la solicitud inicial se realizó con una credencial.
  • Access-Control-Allow-Methods: <métodos>: Indica el método o métodos que se permiten al intentar acceder a un recurso.
  • Access-Control-Allow-Headers: <cabeceras>: Indica las cabeceras HTTP que se pueden utilizar en una solicitud.

He aquí un ejemplo de cómo será la respuesta

HTTP/1.1 204 Sin contenido
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Vary: Access-Control-Request-Headers
Access-Control-Allow-Headers: Content-Type, Accept
Contenido-Longitud: 0
Date: Sat, 16 Nov 2019 11:41:08 GMT 1
Conexión: keep-alive

Cabeceras de solicitud

Estas son las cabeceras que debe contener la solicitud de un cliente para hacer uso del mecanismo CORS.

  • Origen: <origin>: Indica el origen de la solicitud del cliente. Cuando trabaje con un frontend y un backend, como se ha dicho antes, éste será el host de su aplicación frontend.
  • Access-Control-Request-Method: <método>: Se utiliza en una solicitud de verificación previa para indicar el método HTTP que se utilizará para realizar la solicitud.
  • Access-Control-Request-Headers: <cabecera>: Se utiliza en una solicitud de verificación previa para indicar las cabeceras HTTP que se utilizarán para realizar la solicitud.

He aquí un ejemplo del aspecto que tendrá una solicitud

curl -i -X OPTIONS localhost:3001/api \
-H 'Access-Control-Request-Method: GET' \ H
-H 'Access-Control-Request-Headers: Content-Type, Accept' \
-H 'Origen: http://localhost:3000'

Solicitudes de verificación previa

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Después de mencionar las solicitudes de verificación previa aquí y allá, ¿qué podría significar?

Las peticiones de comprobación previa se producen cuando el cliente tiene que enviar una petición de comprobación previa antes de la petición principal. La solicitud de verificación previa es más bien un sondeo para determinar si el servidor admite la solicitud principal que está a punto de realizarse. Cuando se obtiene una confirmación positiva, se envía entonces la solicitud principal.

Cuando una solicitud no es una solicitud preflight, se denomina solicitud simple.

Implementación de CORS

La mayoría de las veces querrá configurar las cosas en el backend de su aplicación. La implementación depende del framework que esté utilizando. Para este tutorial, veremos cómo hacerlo en NodeJS y Rails.

Rails

Le recomiendo que utilice la gema rack-cors. Entonces tendrá que añadir esto a su archivo config/application.rb.

config.middleware.insert_before 0, Rack::Cors do
  allow do
    orígenes '*'
    recurso '*',
       cabeceras: :any,
       expose: %i(access-token expiry token-type uid client),
       methods: %i(get post put patch delete options head),
       credenciales: true
  end
end

NodeJS

En Node.js, esto tendrá el siguiente aspecto

app.all('*', (req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, PATCH, OPTIONS HEAD');
  res.header('Access-Control-Allow-Headers', '*');
  res.header('Access-Control-Allow-Credentials', true);
  next();
});

En el fragmento de código, estamos configurando el origen, los métodos, las cabeceras y las credenciales que deben permitirse para acceder a los recursos disponibles en nuestro servidor. Y para implementarlo en Apache o Nginx, consulte esta guía.

Conclusión

CORS relaja la política para que su navegador pueda acceder a los recursos que usted desee. Entender qué es, por qué es esencial y cómo configurarlo le ayudará a resolver los problemas a los que pueda enfrentarse mientras construye sus aplicaciones web.