20

I need to allow requests from multiple origins: http://localhost:4200, http://localhost:4242, etc., on nginx-ingress version 1.7.1. But I'm not able to do that for multiple origins, because nginx.ingress.kubernetes.io/cors-allow-credentials: true will not work with nginx.ingress.kubernetes.io/cors-allow-origin: "*". It causes the browser to generate CORS error. Maybe someone has a solution for avoiding this error?

this is my config

 annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS, DELETE"
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,X-LANG,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Api-Key,X-Device-Id,Access-Control-Allow-Origin"

Access to XMLHttpRequest at 'https://stage.site.com/api/session' from origin 'http://localhost:4200' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
dezzinto
  • 397
  • 1
  • 2
  • 10

6 Answers6

14

Add the annotation to enable CORS:

nginx.ingress.kubernetes.io/enable-cors: "true"

Be aware that the string "*" cannot be used for a resource that supports credentials (https://www.w3.org/TR/cors/#resource-requests), try with your domain list (comma separated) instead of *

Nicola Ben
  • 10,615
  • 8
  • 41
  • 65
  • 3
    Comma separated list doesn't work. `nginx.ingress.kubernetes.io/cors-allow-origin` only supports one domain, otherwise it resolves to '*'. https://github.com/kubernetes/ingress-nginx/issues/5496 – Marco Ottolini Feb 01 '21 at 16:05
  • I'm using official nginx helm-chart and looks like this annotation related to CORS is not working. https://helm.nginx.com, https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-helm/#adding-the-helm-repository – Andrew Jan 05 '23 at 06:23
8

You can create a second Ingress, with a different domain and cors origin, directing to the same destination. Not the best solution but it works.

Or:

        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/configuration-snippet: |
           more_set_headers "Access-Control-Allow-Origin: $http_origin";
        nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
        nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, 
           OPTIONS, DELETE, PATCH
        nginx.ingress.kubernetes.io/enable-cors: "true"

But attention $http_origin is allowing every origin!

Pierreros
  • 131
  • 1
  • 5
7

This is a fairly requested feature: https://github.com/kubernetes/ingress-nginx/issues/5496

As a current workaround you can use the following snippet to define more than one domain for CORS: https://github.com/kubernetes/ingress-nginx/issues/5496#issuecomment-662798662

A PR has already been submitted and waits for completion. So this should roll out natively during one of the coming releases: https://github.com/kubernetes/ingress-nginx/pull/7134

UPDATE:

As mentioned in the comments this feature has been released.

The following snippet solves the issue:

annotations:
  nginx.ingress.kubernetes.io/enable-cors: "true"
  nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com, https://another-example.com"

More information can be found in the docs: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors

F1ko
  • 3,326
  • 1
  • 9
  • 24
  • 2
    For anyone stumbling on this answer, this is not the case anymore, that feature request has been approved and merged, the docs explain how to do this: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors – Daniel Arechiga Feb 07 '22 at 00:57
2

Updated 2023:

You can now add multiple origins as a comma separated value in cors-allow-origin

Example:

nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com, https://another.com, http://localhost:8000"

Source: Cors Allow Multiple Origin

Yash Thakur
  • 1,172
  • 7
  • 14
1

You can add following to your config to match your two origins against http_origin which ingress received in header and return add *-allow-origin only if pattern has been matched:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_origin ~* "^http://localhost\:(4200|4242)$") {
         add_header Access-Control-Allow-Origin "$http_origin";
      }
  
Kirill Mikhailov
  • 1,029
  • 9
  • 9
0

As Nicola Ben answered above, but this work for me: (Add the annotation to enable CORS)

  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: mybackend-ingress
    namespace: my-backend-namespace
    annotations:
      nginx.ingress.kubernetes.io/cors-allow-headers: Content-Type, authorization
      nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS
      nginx.ingress.kubernetes.io/cors-allow-origin: https://backend.your.url
      nginx.ingress.kubernetes.io/enable-cors: 'true'
nobjta_9x_tq
  • 1,205
  • 14
  • 16