es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué CORS rechaza las solicitudes con Access-Control-Allow-Origin establecido como comodín?

Tengo una interfaz de Angular que hace solicitudes a un servidor nginx. En este momento, el servidor nginx simplemente devuelve una respuesta estática, pero eventualmente se conectará con un servidor de respaldo. Sin embargo, no puedo superar un error de CORS: Firefox informa “No se permite el envío de credenciales de origen cruzado (CORS)” en la pestaña de red.

La configuración es la siguiente:

  • Tanto la interfaz de Angular como nginx se ejecutan en mi máquina local a través del comando “docker-compose”.
  • Cada solicitud pasa por nginx:
    • Las solicitudes de la interfaz de usuario se reenvían a “web-ui” (el DNS de Docker se resolverá en el contenedor Angular).
    • Las solicitudes a “rest-api.mylocal.com” devuelven una respuesta JSON estática de nginx.
  • Se ha modificado “/etc/hosts”:
    • 127.0.0.1 rest-api.mylocal.com
    • 127.0.0.1 web-ui.mylocal.com

Básicamente, abro un navegador y lo dirijo a web-ui.mylocal.com, lo que pasa por nginx y sirve la interfaz de Angular. Luego, la aplicación Angular realiza una solicitud desde el navegador a rest-api.mylocal.com, que se sirve desde nginx. La enrutación funciona correctamente; puedo ver las solicitudes y las respuestas, pero están siendo denegadas por CORS.

La clase Angular tiene este aspecto:

export class CCRestApiService {
  private REST_API_SERVER = "http://rest-api.mylocal.com";

  private _httpClient: HttpClient;

  constructor(private httpClient: HttpClient) {
    this._httpClient = httpClient;
  }

  public getFoo(authDomain: string){
    return this.httpClient.get(
      this.REST_API_SERVER + "/foo",
      { withCredentials: true }
    );
...

La configuración de nginx es la siguiente:

...
    upstream WEBUI {
       server web-ui:4200;
    }
...
    server {
        listen 8080;
        listen [::]:8080;
        server_name web-ui.mylocal.com web-ui localhost;

    # Default
    location / {
        add_header Reverse-Proxy true;
        proxy_set_header X-Real-IP       $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host            $http_host;
        proxy_pass http://WEBUI;
    }
}
...

    server {
        listen 8080;
        listen [::]:8080;
        server_name rest-api.mylocal.com rest-api;

    location /foo {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        return 200 '{"status": "OK"}';
    }
}
...

Se envía una solicitud desde Angular:

GET /foo HTTP/1.1
Host: rest-api.mylocal.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://web-ui.mylocal.com
Connection: keep-alive
Referer: http://web-ui.mylocal.com/

y se recibe la siguiente respuesta:

HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Mon, 29 Nov 2021 21:15:24 GMT
Content-Type: application/json
Content-Length: 34
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true

Entonces, según lo que puedo ver, he dejado totalmente abierto el servidor nginx y definitivamente he configurado “Access-Control-Allow-Credentials”. ¿Por qué Firefox sigue fallando con “No se permite el envío de credenciales de origen cruzado (CORS)”?

Tags:  

Answer

  1. Avatar for davy.ai

    El problema aquí es que la aplicación Angular de frontend está especificando la opción { withCredentials: true } al hacer la solicitud, lo cual no está permitido cuando el servidor emite el encabezado Access-Control-Allow-Origin: *, según se indica en la especificación de CORS.

    Para permitir el envío de credenciales, el servidor tiene que especificar el origen exacto que está permitido a través del encabezado Access-Control-Allow-Origin en lugar de usar el comodín *. En este caso, parece que cambiar el encabezado en la configuración del servidor nginx a `Access-Control-Allow-Origin: http://web-ui.mylocal.com` resolvería el problema.

    Además, puede ser necesario incluir el encabezado Access-Control-Allow-Headers para permitir explícitamente cualquier encabezado personalizado que se esté enviando con la solicitud.

    La configuración de nginx modificada se vería así:

    ...
        server {
            listen 8080;
            listen [::]:8080;
            server_name rest-api.mylocal.com rest-api;
    
            location /foo {
                add_header 'Access-Control-Allow-Origin' 'http://web-ui.mylocal.com' always;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
                add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                return 200 '{"status": "OK"}';
            }
        }
    ...
    

    Con estos cambios, la aplicación Angular debería poder hacer solicitudes al servidor nginx con la opción { withCredentials: true } sin activar el error de CORS.

Comments are closed.