tl; dr; Acerca de la política del mismo origen
Tengo un proceso Grunt que inicia una instancia del servidor express.js. Esto funcionó absolutamente bien hasta ahora, cuando comenzó a mostrar una página en blanco con lo siguiente que aparece en el registro de errores en la consola del desarrollador en Chrome (última versión):
XMLHttpRequest no puede cargar https://www.example.com/ No hay un encabezado 'Access-Control-Allow-Origin' presente en el recurso solicitado. Por lo tanto, no se permite el acceso al origen ' http: // localhost: 4300 '.
¿Qué me impide acceder a la página?
javascript
cors
same-origin-policy
Peter David Carter
fuente
fuente
Respuestas:
tl; dr: hay un resumen al final y títulos en la respuesta para que sea más fácil encontrar las partes relevantes. Sin embargo, se recomienda leer todo, ya que proporciona antecedentes útiles para comprender el por qué, lo que facilita ver cómo se aplica el cómo en diferentes circunstancias.
Acerca de la política del mismo origen
Esta es la Política de Mismo Origen . Es una característica de seguridad implementada por navegadores.
Su caso particular muestra cómo se implementa para XMLHttpRequest (y obtendrá resultados idénticos si usara fetch), pero también se aplica a otras cosas (como imágenes cargadas en un
<canvas>
o documentos cargados en un<iframe>
), solo con implementaciones ligeramente diferentes.(Curiosamente, también se aplica a las fuentes CSS, pero eso se debe a que las fundiciones encontradas insistieron en DRM y no por los problemas de seguridad que generalmente cubre la Política del Mismo Origen).
El escenario estándar que demuestra la necesidad del POE se puede demostrar con tres caracteres :
https://www.[website].com/
en tu ejemplo)http://localhost:4300
en su ejemplo)Alice ha iniciado sesión en el sitio de Bob y tiene algunos datos confidenciales allí. Tal vez sea una intranet de la empresa (accesible solo para navegadores en la LAN), o su banca en línea (accesible solo con una cookie que obtiene después de ingresar un nombre de usuario y contraseña).
Alice visita el sitio web de Mallory, que tiene algo de JavaScript que hace que el navegador de Alice realice una solicitud HTTP al sitio web de Bob (desde su dirección IP con sus cookies, etc.). Esto podría ser tan simple como usar
XMLHttpRequest
y leerresponseText
.La Política del mismo origen del navegador evita que JavaScript lea los datos devueltos por el sitio web de Bob (al que Bob y Alice no quieren que Mallory acceda). (Tenga en cuenta que puede, por ejemplo, mostrar una imagen usando un
<img>
elemento través orígenes debido a que el contenido de la imagen no está expuesto a JavaScript (o Mallory) ... a menos que tirar de la lona en la mezcla, en cuyo caso se va a generar un mismo origen error de infracción).Por qué se aplica la política del mismo origen cuando no cree que debería
Para cualquier URL dada, es posible que el SOP no sea necesario. Un par de escenarios comunes donde este es el caso son:
… Pero el navegador no tiene forma de saber si alguno de los anteriores es cierto, por lo que la confianza no es automática y se aplica el SOP. El permiso debe otorgarse explícitamente antes de que el navegador proporcione los datos que se le dieron a un sitio web diferente.
Por qué la Política del mismo origen solo se aplica a JavaScript en una página web
Las extensiones del navegador
*
, la pestaña Red en las herramientas de desarrollo del navegador y aplicaciones como Postman son software instalado. No pasan datos de un sitio web al JavaScript que pertenece a un sitio web diferente solo porque usted visitó ese sitio web diferente . La instalación de software suele requerir una elección más consciente.No hay un tercero (Mallory) que se considere un riesgo.
*
Las extensiones del navegador deben escribirse con cuidado para evitar problemas de origen cruzado. Consulte la documentación de Chrome, por ejemplo .Por qué puede mostrar datos en la página sin leerlos con JS
Hay una serie de circunstancias en las que el sitio de Mallory puede hacer que un navegador obtenga datos de un tercero y los muestre (por ejemplo, agregando un
<img>
elemento para mostrar una imagen). Sin embargo, no es posible que el JavaScript de Mallory lea los datos en ese recurso, solo el navegador de Alice y el servidor de Bob pueden hacerlo, por lo que aún es seguro.CORS
El encabezado de respuesta
Access-Control-Allow-Origin
HTTP al que se hace referencia en el mensaje de error es parte del estándar CORS que le permite a Bob otorgar explícitamente permiso al sitio de Mallory para acceder a los datos a través del navegador de Alice.Una implementación básica solo incluiría:
… En los encabezados de respuesta para permitir que cualquier sitio web lea los datos.
... permitiría que solo un sitio específico acceda a él, y Bob puede generarlo dinámicamente en función del encabezado de la
Origin
solicitud para permitir que varios sitios, pero no todos, accedan a él.Los detalles de cómo Bob establece ese encabezado de respuesta dependen del servidor HTTP de Bob y / o del lenguaje de programación del lado del servidor. Hay una colección de guías para varias configuraciones comunes que pueden ayudar.
NB: Algunas solicitudes son complejas y envían una solicitud de OPCIONES de verificación previa a la que el servidor tendrá que responder antes de que el navegador envíe GET / POST / PUT / Cualquier solicitud que JS quiera hacer. Las implementaciones de CORS que solo se agregan
Access-Control-Allow-Origin
a URL específicas a menudo se tropiezan con esto.Obviamente, otorgar permiso a través de CORS es algo que Bob solo haría solo si:
¡Pero no soy Bob!
No existe un mecanismo estándar para que Mallory agregue este encabezado porque tiene que provenir del sitio web de Bob, que ella no controla.
Si Bob está ejecutando una API pública, entonces puede haber un mecanismo para activar CORS (tal vez formateando la solicitud de cierta manera, o una opción de configuración después de iniciar sesión en un sitio del Portal de desarrolladores para el sitio de Bob). Sin embargo, este tendrá que ser un mecanismo implementado por Bob. Mallory podría leer la documentación en el sitio de Bob para ver si hay algo disponible, o podría hablar con Bob y pedirle que implemente CORS.
Mensajes de error que mencionan "Respuesta para verificación previa"
Algunas solicitudes de origen cruzado tienen verificación previa .
Esto sucede cuando (en términos generales) intenta realizar una solicitud de origen cruzado que:
enctype
).Si está haciendo correctamente algo que necesita una verificación previa
En estos casos, el resto de esta respuesta aún se aplica, pero también debe asegurarse de que el servidor pueda escuchar la solicitud de verificación previa (que será
OPTIONS
(y noGET
,POST
o lo que sea que estaba tratando de enviar) y responder a ella con el derechoAccess-Control-Allow-Origin
header sino tambiénAccess-Control-Allow-Methods
yAccess-Control-Allow-Headers
para permitir sus métodos o encabezados HTTP específicos.Si está activando una verificación previa por error
A veces, las personas cometen errores al intentar construir solicitudes Ajax y, a veces, estos provocan la necesidad de una verificación previa. Si la API está diseñada para permitir solicitudes de origen cruzado, pero no requiere nada que necesite una verificación previa, esto puede interrumpir el acceso.
Los errores comunes que desencadenan esto incluyen:
Access-Control-Allow-Origin
y otros encabezados de respuesta CORS en la solicitud. Estos no pertenecen a la solicitud, no hacen nada útil (¿cuál sería el punto de un sistema de permisos en el que podría otorgarse permiso a sí mismo?), Y deben aparecer solo en la respuesta.Content-Type: application/json
encabezado en una solicitud GET que no tiene un cuerpo de solicitud para describir el contenido (generalmente cuando el autor confundeContent-Type
yAccept
).En cualquiera de estos casos, eliminar el encabezado de solicitud adicional a menudo será suficiente para evitar la necesidad de una verificación previa (que resolverá el problema al comunicarse con API que admiten solicitudes simples pero no solicitudes de verificación previa).
Respuestas opacas
A veces es necesario realizar una solicitud HTTP, pero no es necesario leer la respuesta. por ejemplo, si está publicando un mensaje de registro en el servidor para su grabación.
Si está utilizando la
fetch
API (en lugar deXMLHttpRequest
), puede configurarla para que no intente utilizar CORS.Tenga en cuenta que esto no le permitirá hacer nada que necesite que haga CORS. No podrá leer la respuesta. No podrá realizar una solicitud que requiera una verificación previa.
Le permitirá hacer una solicitud simple, no ver la respuesta y no llenar la Consola del desarrollador con mensajes de error.
Cómo hacerlo se explica por el mensaje de error de Chrome que aparece cuando realiza una solicitud utilizando
fetch
y no obtiene permiso para ver la respuesta con CORS:Así:
Alternativas a CORS
JSONP
Bob también podría proporcionar los datos utilizando un truco como JSONP, que es la forma en que las personas cruzaban el origen Ajax antes de que apareciera CORS.
Funciona presentando los datos en forma de un programa JavaScript que inyecta los datos en la página de Mallory.
Requiere que Mallory confíe en Bob para no proporcionar código malicioso.
Tenga en cuenta el tema común: el sitio que proporciona los datos debe decirle al navegador que está bien que un sitio de terceros acceda a los datos que está enviando al navegador.
Dado que JSONP funciona agregando un
<script>
elemento para cargar los datos en forma de un programa JavaScript que llama a una función que ya está en la página, intentar usar la técnica JSONP en una URL que devuelve JSON fallará, generalmente con un error CORB, porque JSON no es JavaScript.Mueva los dos recursos a un solo origen
Si el documento HTML en el que se ejecuta JS y la URL que se solicita están en el mismo origen (compartiendo el mismo esquema, nombre de host y puerto), la Política del mismo origen otorga permiso de forma predeterminada. CORS no es necesario.
Un proxy
Mallory podría usar el código del lado del servidor para obtener los datos (que luego podría pasar de su servidor al navegador de Alice a través de HTTP como de costumbre).
O bien:
Ese código del lado del servidor podría ser escrito y alojado por un tercero (como CORS Anywhere). Tenga en cuenta las implicaciones de privacidad de esto: el tercero puede monitorear quién es proxy qué en sus servidores.
Bob no necesitaría otorgar ningún permiso para que eso suceda.
No hay implicaciones de seguridad aquí, ya que eso es solo entre Mallory y Bob. Bob no puede pensar que Mallory es Alice y proporcionar a Mallory datos que deben mantenerse confidenciales entre Alice y Bob.
En consecuencia, Mallory solo puede utilizar esta técnica para leer datos públicos .
Sin embargo, tenga en cuenta que tomar contenido del sitio web de otra persona y mostrarlo por su cuenta podría ser una violación de los derechos de autor y exponerlo a acciones legales.
Escribir algo que no sea una aplicación web
Como se indica en la sección "Por qué la Política del mismo origen solo se aplica a JavaScript en una página web", puede evitar el SOP si no escribe JavaScript en una página web.
Eso no significa que no pueda continuar usando JavaScript y HTML, pero podría distribuirlo usando algún otro mecanismo, como Node-WebKit o PhoneGap.
Extensiones de navegador
Es posible que una extensión del navegador inyecte los encabezados CORS en la respuesta antes de que se aplique la Política del mismo origen.
Estos pueden ser útiles para el desarrollo, pero no son prácticos para un sitio de producción (pedir a cada usuario de su sitio que instale una extensión de navegador que deshabilite una función de seguridad de su navegador no es razonable).
También tienden a funcionar solo con solicitudes simples (fallan al manejar solicitudes de OPCIONES de verificación previa).
Tener un entorno de desarrollo adecuado con un servidor de desarrollo local suele ser un mejor enfoque.
Otros riesgos de seguridad
Tenga en cuenta que SOP / CORS no mitigan los ataques de inyección de XSS , CSRF o SQL que deben manejarse de forma independiente.
Resumen
fuente
El servidor de destino debe permitir la solicitud de origen cruzado. Para permitirlo a través de Express, simplemente maneje la solicitud de opciones http:
fuente
Como esto no se menciona en la respuesta aceptada.
Puede hacer uso de Solicitudes simples .
Para realizar una 'Solicitud simple', la solicitud debe cumplir varias condiciones. Por ejemplo, sólo permite
POST
,GET
yHEAD
método, así como permitiendo sólo algunas cabeceras dado (usted puede encontrar todas las condiciones aquí ).Si el código de su cliente no establece explícitamente los encabezados afectados (por ejemplo, "Aceptar") con un valor fijo en la solicitud, es posible que algunos clientes establezcan estos encabezados automáticamente con algunos valores "no estándar", lo que hace que el servidor no los acepte como Solicitud simple - que le dará un error CORS.
fuente
Esto sucede debido al error CORS. CORS son las siglas de Cross Origin Resource Sharing. En pocas palabras, este error se produce cuando intentamos acceder a un dominio / recurso desde otro dominio.
Lea más sobre esto aquí: error CORS con jquery
Para solucionar esto, si tiene acceso al otro dominio, tendrá que permitir Access-Control-Allow-Origin en el servidor. Esto se puede agregar en los encabezados. Puede habilitar esto para todas las solicitudes / dominios o un dominio específico.
Cómo hacer que funcione una solicitud de publicación de recursos compartidos de origen cruzado (CORS)
Estos enlaces pueden ayudar
fuente
Este problema de CORS no se desarrolló más (por otras causas).
Actualmente tengo este problema por diferentes motivos. Mi interfaz también está devolviendo el error de encabezado 'Access-Control-Allow-Origin'.
Solo que señalé la URL incorrecta, por lo que este encabezado no se reflejó correctamente (en lo que supongo que sí). localhost (front-end) -> llamar a http no seguro (se supone que es https), asegúrese de que el punto final de la API desde el front-end apunte al protocolo correcto.
fuente
Recibí el mismo error en la consola de Chrome.
Mi problema era que intentaba ir al sitio usando en
http://
lugar dehttps://
. Así que no había nada que arreglar, solo tenía que ir al mismo sitio usandohttps
.fuente
La solicitud "Obtener" con la adición de encabezados se transforma en la solicitud "Opciones". Entonces ocurren problemas de política de Cors. Tienes que implementar la solicitud de "Opciones" en tu servidor.
fuente
Debe habilitar CORS para que funcione.
fuente