Cross Origin Resource Sharing (CORS) o en español, Intercambio de Recursos de Origen Cruzado, es un mecanismo de seguridad para la solicitud e intercambio de recursos entre aplicaciones con dominios diferentes. En pocas palabras, si las solicitudes HTTP se realizan desde un dominio diferente al dominio del backend, estas serán rechazadas.
Si eres desarrollador o desarrolladora front-end, tendrás problemas de CORS a lo largo de tu carrera y en múltiples oportunidades. Pero no te preocupes, es completamente normal y vamos a ver de qué se trata para evitar dolores de cabeza.
Cómo habilitar el dominio
Si CORS no está habilitado en el backend que estés consultando, las peticiones se bloquearán y verán un error en la consola de desarrollo del navegador.
Dependerá del equipo back end o de ti si también estás desarrollándolo, de habilitar el dominio del front-end desde el cual se ejecutarán las peticiones.
La habilitación del dominio suele ser muy sencilla y dependerá del lenguaje de programación y framework que estés utilizando, pero suele verse de la siguiente manera:
// MAL: Un * da permisos a cualquier dominio de realizar peticiones, es una muy mala práctica de seguridad.cors({origin:'*'})// BIEN: Lo ideal es solo permitir los dominios que queremos autorizar a realizar peticiones.cors({origin:['mydomain.com','app.mydomain.com']})
Entornos donde se produce este error
Este error suele producirse principalmente en entornos de desarrollo o productivos reales, en servidores en la nube. No es tan habitual que suceda en entornos locales, ya que aplicaciones como Postman o Insomnia para realizar pruebas de petición HTTP, cambian el origen de las peticiones y evitan este problema.
En el caso que expone el profesor es cuando la URL es de la estructura: https://domain.com/api/
La forma en como se implementa funciona muy bien, incluso para cuando el valor que dice api es igual a otro string funciona sin problemas, como por ejemplo group, la URL sería: https://domain.com/group/
Hasta ahí todo sin problemas, pero que pasa cuando la URL contiene solo el dominio, por ejemplo:
Busqué en varias fuentes y no había nada claro, quiero mostrar como yo manejé el problemas de CORDS para una URL que solo tenga el dominio.
Primero: La URL que dejo establecida en el eviroment o dentro del mismos servicio que voy a consumir el servicio http, la dejo de la forma: /api/ (que es el end point tal como el profe dice). Entonces el servicio queda de la siguiente forma:
import{Injectable}from'@angular/core';import{HttpClient,HttpParams}from"@angular/common/http"import{Observable}from'rxjs';@Injectable({providedIn:'root'})exportclassImagesServicesService{constructor(privatehttpClient:HttpClient){} url ="/api/"// Hay un proxy de desarrollo para evitar problemas de CORDSgetInf():Observable<any>{returnthis.httpClient.get(this.url)}}
Segundo: en el proxy añado un parámetro adicional para reescribir el path de la URL. Queda de la siguiente forma:
Con esto cuando haga una petición http el proxy me modifica la URL que solicito, me pone el target y modifica el api quitandolo.
Espero que sea de ayuda.
Gracias bro!
Muy interesante, gracias Andrés por compartir1
Esta clase era necesaria desde el curso de angular 8
Excelente clase, desde mis inicios, los CORS siempre han sido un dolor de cabeza, que solo se han resuelto con paños de agua tibia. Una explicación clara como esta ayuda inmensamente. Gracias :D
Para el que le salga este error
[SELF_SIGNED_CERT_IN_CHAIN]
Lo solucioné colocando en "false" la propiedad secure del proxy, asi:
Entiendo que así se evita que se revise el certificado, pero ¿Alguien sabe una mejor forma de solucionar ese problema?
Muy buena explicacion sobre el problema y como resolverlo.
Todo por no tomar mis clases a tiempo xD
Recientemente tuve este problema, ya fue la segunda vez de hecho, un aplicativo angular se conectaba a un web api de .net framework, recuerdo que la solución fue una configuración en IIS, sin embargo, recientemente me pasó de nuevo, ésta vez más complicado, Igualmente un cliente de angular esta vez a un API en Net Core montada en un microservicio de kubernetes, Obviamente la petición de mi k8s venía del host de mi nodo máster y el microservicio se exponía desde un load balancer en el mismo clúster, pero aparte con https... Pff que lio, Aunque es muy buena la solución temporal que muestra el profe, efectivamente es un problema de backEnd y se debe de corregir desde el api, esta segunda vez que tuve el problema se tenía que agregar una política al ConfigureServices de la clase startUp
Hola Iván, yo me encuentro en una situación similar a la que menciona en el primer caso, tengo una aplicación que estoy desarrollando y la desplegué on premise en una ambiente de pruebas para que mi cliente la revise, resulta que cuando uso mi aplicación en mi red corporativa todo funciona bien, pero cuando mi cliente la prueba en casa, los métodos PUT y DELETE fallan. He revisado en internet y seguido algunas recomendaciones como https://stackoverflow.com/questions/10906411/asp-net-web-api-put-delete-verbs-not-allowed-iis-8 pero no logro resolver el problema. De casualidad podrías compartir un poco más la solución que encontró. Gracias
que buena clase!
Al de ejecutar el comando ng serve --proxy-config ./proxy.config.json genera el siguiente error:
An unhandled exception occurred: Proxy config file C:\angular-APIS-main\proxy.config.json does not exist.
See "C:\Users\LOCAL\AppData\Local\Temp\ng-RkE5EX\angular-errors.log" for further details.
Teniendo previamente generado el archivo proxy.config.json, se revisa el repositorio donde se encuentra alojado el proyecto y no se encuentra.
¿Alguien sabe por qué no creo el archivo en la ruta indicada?
De igual manera se encontró solución copiando el JSON y creándolo manualmente en el repositorio indicado.
como hizo le profe Nicolás para que le saliera el problema de CORS?
no se como le aparecio al profesor, pero a mi me sucedio algo parecido cuando estaba haciendo mi backend en spring boot, y en el navegador me salio un problema de cors-origin, me toco habilitar desde el back a angular para que pudiera recibir peticiones.
Buenas noches, quisiera saber si esta configuración ha cambiado en la version 13 de angular
Al parecer creo que no
lo necesitaba, porque no me consumía la API que realice en Java, y este video lo estaba buscando, me quedo asi:
Le pedí a ChatGPT que me lo explicara CORS cómo si tuviera 12 años. Aquí pueden leer su respuesta
jajajaja estuvo bueno el ejemplo
Exelente aporte los CORS siempre son una molestia ... hasta hoy
Buenas tardes:
No entendí este capítulo, en verdad que venía siguiendo al profesor sin problema y accediendo a la heroupapp api, sin CORS, pero al seguir la explicación y crear el proxy.config.json fichero y demás, al correr en consola la order start:proxy, me salta este error:
start:proxy : El término 'start:proxy' no se reconoce como nombre de un cmdlet, función, archivo de script o programa
ejecutable. Compruebe si escribió correctamente el nombre o, si incluyó una ruta de acceso, compruebe que dicha ruta es
correcta e inténtelo de nuevo.
En línea: 1 Carácter: 1
No entiendo a qué es debido, he comprobado la ruta varias veces y todo está igual que como lo escribe el profesor, debe ser algo mío en local pero que no sé qué es ni como resolver para poder utilizar este proxy en el environment de DESARROLLO
Quedo ansiosa a la espera de sus valiosos aportes.
Un saludo cordial,
Hola! el comando completo es npm run start:proxy, poniéndolo de esta forma ya te debería funcionar.
Si tuviera múltiples entornos de backend donde tengo que probar localmente mi frontend, ¿Tengo que crear un proxy.conf.json por cada backend aunque los tenga configurado por environment?
y como se hizo eso de los CORS?
En el caso de los desarrolladores Backend, qué tendrían que hacer ellos específicamente? Hace poco hice un proyecto con FastAPI, en el cual genero una API de un CRUD de películas (crear películas, obtener películas, actualizarlas, eliminarlas, etc.) con despliegue en la nube y todo, y en la instancia en la nube que corre la app hecha en FastAPI, tuve que configurar el siguiente comando al momento de arranque de la app:
$ uvicorn main:app --host 0.0.0.0--port 8000
Con poner --host 0.0.0.0 se solucionaría éste inconveniente de cara al backend? porque como tal mi aplicación está ya corriendo en la nube y al probar las peticiones a la api con swagger desde el navegador, todo funciona correcto, pero hasta ahora no lo he probado desde alguna aplicación frontend desarrollada por mi.
Hola...
Si el servicio(API) que estoy consumiendo, desde mi aplicación, es un mock creado en postman, como se podría habilitar para que en ambiente preproducción, no se generaran error de CORS?
Hola, puedes crear un proxy desde Angular para que corra en donde estés corriendo tu Mock API, pero recuerda que esto sería solo para desarrollo podrías ver que opciones te ofrece tu Mock API en Postman si lo quieres probar en un ambiente productivo.
Solución temporal para Cors con proxy
Una alternativa que podemos usar para este problema de CORS si no tenemos control sobre el servidor seria utilizar el proyecto Cors-anywhere que prácticamente haría lo mismo que postman /insomnia modificando el origen para que nuestra solicitud no sea bloqueada.