'How to prevent "Access-Control-Allow-Origin" header contain multiple value

This is my Nginx CORS config:

set $cors '';

if ($http_origin ~ '^https?://(localhost|www\.beloveddais\.com|www\.beloveddais\.com)') {
    set $cors 'true';
}


if ($cors = 'true') {
    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
    # required to be able to read Authorization header in frontend
    add_header 'Access-Control-Expose-Headers' 'Authorization' always;
}

if ($request_method = 'OPTIONS') {
    # Tell client that this pre-flight info is valid for 20 days
    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
}

if ($request_method = 'GET') {
    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
}

if ($request_method = 'POST') {
    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
}

On my browser console I keep getting:

Failed to load http://beloveddais.win/socket.io/?EIO=3&transport=polling&t=M6yTqBe: The 'Access-Control-Allow-Origin' header contains multiple values 'http://beloveddais.com, http://beloveddais.com', but only one is allowed. Origin 'http://beloveddais.com' is therefore not allowed access.

Please I need help to prevent this multiple header stuff. This has really wasted my time.



Solution 1:[1]

Your config is adding Access-Control-Allow-Origin twice. This is because of construction of your config file. 1st time it is added because of ($cors = 'true') condition, and 2nd time because of ($request_method = 'OPTIONS') condition.

You should make clear policy of sending headers and prepare conditions so they are mutual exclusive, so no header will be sent multiple times.

Solution 2:[2]

I had this same error in following scenario.

I have Springboot RESTAPI and Angular client.

Angular Client calls the API and all end points are behaving as expected.

CAUSE (IN MY SCENARIO)

However, one endpoint in my API calls another API.

That other API returns response including the headers containing its own Access-Control-Allow-Origin. Then my API adds its own Access-Control-Allow-Origin resulting in two Access-Control-Allow-Origin headers which is not allowed by browsers.

My CORS settings are right because I know all other endpoints are working fine and are returning only one Access-Control-Allow-Origin.

SOLUTION

So, the solution I did is that in the Controller calling other API, and once other API returns response, I would get the body out of that response and create a new ResponseEntity from it.

This results in only my API returning its own Access-Control-Allow-Origin and all is working fine.

I hope this explanation of the cause and solution will help others since I see lots of people are asking the same question.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 DevilaN
Solution 2 pixel