Instantly share code, notes, and snippets.

Embed
What would you like to do?
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 comment has been minimized.

Show comment
Hide comment
@epicserve

epicserve Feb 27, 2012

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 *.

epicserve commented Feb 27, 2012

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

This comment has been minimized.

Show comment
Hide comment
@jaseemabid

jaseemabid Apr 12, 2012

Thanks a lot. This saved my day :)

jaseemabid commented Apr 12, 2012

Thanks a lot. This saved my day :)

@yishenggudou

This comment has been minimized.

Show comment
Hide comment
@yishenggudou

yishenggudou Apr 16, 2012

good example for config options

yishenggudou commented Apr 16, 2012

good example for config options

@Nek

This comment has been minimized.

Show comment
Hide comment
@Nek

Nek May 23, 2012

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

Nek commented May 23, 2012

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

@mrdevin

This comment has been minimized.

Show comment
Hide comment
@mrdevin

mrdevin Aug 2, 2012

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;
 }

mrdevin commented Aug 2, 2012

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

This comment has been minimized.

Show comment
Hide comment
@michiel

michiel Sep 13, 2012

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

Owner

michiel commented Sep 13, 2012

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

@alexjs

This comment has been minimized.

Show comment
Hide comment
@alexjs

alexjs Nov 28, 2012

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.

alexjs commented Nov 28, 2012

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

This comment has been minimized.

Show comment
Hide comment
@remoe

remoe Dec 18, 2012

Thanks for this. I use:

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

remoe commented Dec 18, 2012

Thanks for this. I use:

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

@nanonyme

This comment has been minimized.

Show comment
Hide comment
@nanonyme

nanonyme Feb 11, 2013

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?

nanonyme commented Feb 11, 2013

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

This comment has been minimized.

Show comment
Hide comment
@kamoljan

kamoljan May 30, 2013

Thanks a lot!

kamoljan commented May 30, 2013

Thanks a lot!

@andreparames

This comment has been minimized.

Show comment
Hide comment
@andreparames

andreparames Oct 22, 2013

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 '*'.

andreparames commented Oct 22, 2013

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 '*'.

@puppeteer701

This comment has been minimized.

Show comment
Hide comment
@puppeteer701

puppeteer701 Jul 8, 2014

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;  

    }

puppeteer701 commented Jul 8, 2014

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

This comment has been minimized.

Show comment
Hide comment
@Meekohi

Meekohi Aug 18, 2014

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;

Meekohi commented Aug 18, 2014

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

This comment has been minimized.

Show comment
Hide comment
@meawoppl

meawoppl Aug 22, 2014

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

meawoppl commented Aug 22, 2014

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

@TimmyCP

This comment has been minimized.

Show comment
Hide comment
@TimmyCP

TimmyCP Sep 20, 2014

Place this in nginx.conf or server blocks?

TimmyCP commented Sep 20, 2014

Place this in nginx.conf or server blocks?

@aronwoost

This comment has been minimized.

Show comment
Hide comment
@aronwoost

aronwoost Jun 26, 2015

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+).

aronwoost commented Jun 26, 2015

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

This comment has been minimized.

Show comment
Hide comment
@brupm

brupm Jul 1, 2015

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.

brupm commented Jul 1, 2015

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.

@niksmac

This comment has been minimized.

Show comment
Hide comment
@niksmac

niksmac commented Aug 18, 2015

There is a better page http://enable-cors.org/server.html

@GromNaN

This comment has been minimized.

Show comment
Hide comment
@GromNaN

GromNaN Dec 11, 2015

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";

GromNaN commented Dec 11, 2015

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

This comment has been minimized.

Show comment
Hide comment
@yinyanfr

yinyanfr Feb 3, 2016

where do i put them?

yinyanfr commented Feb 3, 2016

where do i put them?

@hasangilak

This comment has been minimized.

Show comment
Hide comment
@hasangilak

hasangilak May 11, 2016

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 ;)

hasangilak commented May 11, 2016

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

This comment has been minimized.

Show comment
Hide comment
@rowen17

rowen17 May 17, 2016

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

rowen17 commented May 17, 2016

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

This comment has been minimized.

Show comment
Hide comment
@maxim25

maxim25 Jun 2, 2016

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?

maxim25 commented Jun 2, 2016

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

This comment has been minimized.

Show comment
Hide comment
@Skydev0h

Skydev0h Jun 5, 2016

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

Skydev0h commented Jun 5, 2016

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

@marianacristina666

This comment has been minimized.

Show comment
Hide comment
@marianacristina666

marianacristina666 Sep 2, 2016

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

marianacristina666 commented Sep 2, 2016

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

@loustler

This comment has been minimized.

Show comment
Hide comment
@loustler

loustler Sep 5, 2016

Thanks.
It is so useful and helpful for me.

loustler commented Sep 5, 2016

Thanks.
It is so useful and helpful for me.

@tomleader

This comment has been minimized.

Show comment
Hide comment
@tomleader

tomleader Oct 12, 2016

Line 28

add_header 'Content-Type' 'text/plain charset=UTF-8';

It seems the semicolon is missing, maybe ' text/plain; charset=UTF-8' is more standard

tomleader commented Oct 12, 2016

Line 28

add_header 'Content-Type' 'text/plain charset=UTF-8';

It seems the semicolon is missing, maybe ' text/plain; charset=UTF-8' is more standard

@Cervenka

This comment has been minimized.

Show comment
Hide comment
@Cervenka

Cervenka Oct 18, 2016

In case you want to use the wildcard origin where possible but also allow credentials if the origin was sent along use following:

set $acac true;
if ($http_origin = ''){
    set $acac false;
    set $http_origin "*";
 }
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials $acac;

Cervenka commented Oct 18, 2016

In case you want to use the wildcard origin where possible but also allow credentials if the origin was sent along use following:

set $acac true;
if ($http_origin = ''){
    set $acac false;
    set $http_origin "*";
 }
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials $acac;
@x2es

This comment has been minimized.

Show comment
Hide comment
@x2es

x2es Oct 24, 2016

why do you specify content-type related headers if no body for 204 response?
https://gist.github.com/michiel/1064640#file-cors-nginx-conf-L28-L29

x2es commented Oct 24, 2016

why do you specify content-type related headers if no body for 204 response?
https://gist.github.com/michiel/1064640#file-cors-nginx-conf-L28-L29

@gansbrest

This comment has been minimized.

Show comment
Hide comment
@gansbrest

gansbrest Apr 17, 2017

Here is shorter version of access control allow origin for Nginx that should get you started.

gansbrest commented Apr 17, 2017

Here is shorter version of access control allow origin for Nginx that should get you started.

@GraniteConsultingReviews

This comment has been minimized.

Show comment
Hide comment
@GraniteConsultingReviews

GraniteConsultingReviews Sep 1, 2017

I having problem in this code This giving me error.

GraniteConsultingReviews commented Sep 1, 2017

I having problem in this code This giving me error.

@defaultwp

This comment has been minimized.

Show comment
Hide comment
@defaultwp

defaultwp Nov 4, 2017

I have put this code in location inside /site-enabled/ but its still giving error on http://defaultwallpaper.com Please help.

defaultwp commented Nov 4, 2017

I have put this code in location inside /site-enabled/ but its still giving error on http://defaultwallpaper.com Please help.

@hasangilak

This comment has been minimized.

Show comment
Hide comment
@hasangilak

hasangilak May 5, 2018

syntax error. missing closing ' in checking OPTIONS. 'Content-Length should be 'Content-Length'
add_header 'Content-Length 0;

hasangilak commented May 5, 2018

syntax error. missing closing ' in checking OPTIONS. 'Content-Length should be 'Content-Length'
add_header 'Content-Length 0;

@hasantayyar

This comment has been minimized.

Show comment
Hide comment

hasantayyar commented Jun 14, 2018

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