Create a gist now

Instantly share code, notes, and snippets.

Wide-open CORS config for nginx
#
# Wide-open CORS config for nginx
#
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
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 = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
@epicserve

This doesn't seem to work for me ... I'm uisng nginx/1.0.5. For testing I replaced http://10.140.10.40 with *.

@jaseemabid

Thanks a lot. This saved my day :)

@yishenggudou

good example for config options

@Nek

If only I could see this before wasting 5 hours of time... Thanks a lot for saving the rest of my day! :)

@mrdevin

For me I hade to return 204 otherwise the browser would hang and then timeout on the option request:
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;

    return 204;
 }
@michiel
Owner

Updated with 204 return for OPTIONS (mrdevin) and wildcard '*' for Access-Control-Allow-Origin (epicserve).

@alexjs

I've updated this in https://gist.github.com/4165271 to add a poor man's whitelist. I'm not really sure where having Access-Control-Allow-Origin as wildcard would cause too many issues, but some people may be extra conscious. We use a simple-ish regexp to match valid URLs. Please note that I haven't load tested this, so I don't know what kind of effect it'll have.

@remoe

Thanks for this. I use:

add_header "Access-Control-Allow-Origin" $http_origin;

@nanonyme

FWIW HTTP/1.1 RFC says response from OPTIONS is not cacheable. Doesn't that mean a browser must ignore your Access-Control-Max-Age header?

@kamoljan

Thanks a lot!

@andreparames

From MDN:

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding.

I've confirmed that at least Firefox will block a request with cookies if the Access-Control-Allow-Origin is set to '*'.

@mato75

This does not work for me

location / {
             add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

        root   share/nginx/html;
        proxy_pass         https://dddd.dd.com;
        proxy_set_header   Host dddd.dd.com;  

    }
@Meekohi

You cannot use a wildcard Access-Control-Allow-Origin if you want to use xhrFields: {withCredentials:true} to send cookies/basicauth. In that case you must use the exact origin:

add_header "Access-Control-Allow-Origin" $http_origin;

@meawoppl

When starting to use this Chrome will cache the earlier (CORS failed) requests. Reset the cache to get things working!

@TimmyCP

Place this in nginx.conf or server blocks?

@aronwoost

As stated in the docs add_header does not have any effect on 4xx and 5xx responses.

So save the two hours I just wasted and add always to your add_header (works with nginx 1.7.5+).

@brupm

By adding this CORS block to my nginx config I now see my initial OPTIONS request followed by an identical GET request (incorrect duplicate) - Any idea what could be causing this?

https://gist.github.com/brupm/1b2c69cbf8f9612ee304

I suspect it's the return 204 line.

@GromNaN

If you use a cache server, you must add a Vary: Origin to the response.

add_header "Access-Control-Allow-Origin" $http_origin;
add_header "Vary" "Origin";
@yinyanfr

where do i put them?

@hasangilak

for anybody on ubuntu first install
sudo apt-get install nginx-extras
and then
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

turn all add_header into more_set_headers
and it will work ;)

@rowen17
rowen17 commented May 17, 2016 edited

On add_header, if your server will intentionally throw status code other than 200, 201, 204, 206, 301, 302, 303, 304, or 307 (Ex. 400 or 422) you should add always on each line

So instead of

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';

Use

add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;

Source

@maxim25
maxim25 commented Jun 2, 2016 edited

When I add

add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;

I get:
nginx: [emerg] invalid number of arguments in "add_header" directive in /etc/nginx/sites-enabled/foobar:12
nginx: configuration file /etc/nginx/nginx.conf test failed

Any idea?

@Skydev0h
Skydev0h commented Jun 5, 2016 edited

@maxim25, Are you sure that your nginx is 1.7.5 or newer?

@marianacristina666

If 'Access-Control-Allow-Credentials' is set "TRUE"
the wildcard (*) in the Allow-Origin dont work!

@loustler

Thanks.
It is so useful and helpful for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment