# | |
# CORS header support | |
# | |
# One way to use this is by placing it into a file called "cors_support" | |
# under your Nginx configuration directory and placing the following | |
# statement inside your **location** block(s): | |
# | |
# include cors_support; | |
# | |
# As of Nginx 1.7.5, add_header supports an "always" parameter which | |
# allows CORS to work if the backend returns 4xx or 5xx status code. | |
# | |
# For more information on CORS, please see: http://enable-cors.org/ | |
# Forked from this Gist: https://gist.github.com/michiel/1064640 | |
# | |
set $cors ''; | |
if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.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-Max-Age' 1728000; | |
add_header 'Content-Type' 'text/plain charset=UTF-8'; | |
add_header 'Content-Length' 0; | |
return 204; | |
} |
This comment has been minimized.
This comment has been minimized.
@semusi You should place it within the curly braces in the server { ... } block of your configuration, which you will find inside the file(s) in /etc/nginx/sites-enabled/. It shouldn't matter where you place it within the server block. Edit: You should put it in your location block(s). If you have multiple server blocks that you want to use CORS with, you can also save this as a separate file in /etc/nginx/cors and within your server blocks, enter "include cors;" which will include the file. |
This comment has been minimized.
This comment has been minimized.
Thanks for this code. |
This comment has been minimized.
This comment has been minimized.
Is there any workaround to set the headers (and get the content) when the server returns a 4xx or 5xx status code? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I just tried this for an issue I'm having getting a meteor android app connected, but "nginx -t" gives: 2015/06/02 12:31:55 [emerg] 7055#0: "add_header" directive is not allowed here in /etc/nginx/sites-enabled/mysite.com.conf:22 I'm running nginx 1.8.0 on Ubuntu 14.04. Has something changed recently? |
This comment has been minimized.
This comment has been minimized.
I have a same problem with chrisco 23 |
This comment has been minimized.
This comment has been minimized.
@chrisco23 If you are using Ubuntu then should install
|
This comment has been minimized.
This comment has been minimized.
awesome! thanks! |
This comment has been minimized.
This comment has been minimized.
Thanks for this! For people having trouble saying that the |
This comment has been minimized.
This comment has been minimized.
Is there a reason why you separated the first 2 if statements? Will it not work if I combine and eliminate the variable? |
This comment has been minimized.
This comment has been minimized.
One painful caveat I just discovered is that nginx (as of 1.9) treats the |
This comment has been minimized.
This comment has been minimized.
Thanks for this gist. I forked it for Nginx > 1.9 with support for 4xx and 5xx response and exposition of authorization header. https://gist.github.com/agouriou/735daacf7530675552ff248f319a07d9 |
This comment has been minimized.
This comment has been minimized.
Does this work if I am running javascript on my page that manipulates the page on the nginx server? For example: I keep getting |
This comment has been minimized.
This comment has been minimized.
Thanks for this! It works great. Something I discovered: When serving up polygons, if they are styled with a fill opacity of 0.0, GetFeatureInfo will not return any data (unless you click the outline of the polygon). Changing style fill opacity to 0.1 fixed this. |
This comment has been minimized.
This comment has been minimized.
Thanks for the comments guys, I've updated this gist to include support the "always" parameter for nginx 1.7.5+ so that you can get non-200 responses returned back correctly. I've also added a line for exposing the authorization header based on @agouriou's fork. In addition, I removed the proprietary |
This comment has been minimized.
This comment has been minimized.
does it work for both of http and https? |
This comment has been minimized.
This comment has been minimized.
Yes, @fakirpic. The 's' is optional because of the question mark |
This comment has been minimized.
This comment has been minimized.
This doesn't appear to work if included in a location that uses |
This comment has been minimized.
This comment has been minimized.
Correct me if I'm wrong, but you're defining the |
This comment has been minimized.
This comment has been minimized.
I've added those codes above in my server { . . . } as suggested. I kept getting
Here is my entire configs
Please let me know what I did wrong !!! |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@bunlongheng you must to put your add_header inside |
This comment has been minimized.
This comment has been minimized.
Please read this comment if you plan to use the above gist.The above code contains a very serious vulnerability. Specifically this line: Vulnerable
SafeNote, the $ at the end of the regex, terminating the line. What is actually meant is:
Without the extra $, you have essentially turned off all security for your website. The attacker would do the following to exploit this.
Please feel free to ping me if you have any questions. |
This comment has been minimized.
This comment has been minimized.
You could use nginx maps in favor of the regex:
This also prevents the attack detailed by @ejcx |
This comment has been minimized.
This comment has been minimized.
Here is my version of doing nginx access control allow origin that avoids some of the duplication. |
This comment has been minimized.
This comment has been minimized.
I created a new file in /etc/nginx/conf.d 'cors.conf' with the the below configuration. Note: My use case was to enable Cors for an nginx reverse proxy which forwards the request to my flask application on docker. My front-end is hosted on AWS S3. server {
|
This comment has been minimized.
This comment has been minimized.
I really don't know why this is working for you, guys. |
This comment has been minimized.
This comment has been minimized.
If you really need sane CORS functionality, it's better to use some Lua. |
This comment has been minimized.
This comment has been minimized.
save your soul and use the lua below! |
This comment has been minimized.
This comment has been minimized.
Please be aware that this will allow your resources to be accessed cross-origin by anybody with a domain name like http://localhost-hacker.biz or https://localhost.blackhat.org. Add a |
This comment has been minimized.
This comment has been minimized.
My complete script that works both on my website and localhost: In this script, my server is server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name blog.mywebsite.com;
root /var/www/ghost/system/nginx-root;
ssl_certificate /etc/letsencrypt/blog.mywebsite.com/fullchain.cer;
ssl_certificate_key /etc/letsencrypt/blog.mywebsite.com/blog.mywebsite.com.key;
include /etc/nginx/snippets/ssl-params.conf;
set $cors_origin "";
set $cors_cred "";
set $cors_header "";
set $cors_method "";
if ($http_origin ~ '^https?://(localhost|mywebsite\.com)$') {
set $cors_origin $http_origin;
set $cors_cred true;
set $cors_header $http_access_control_request_headers;
set $cors_method $http_access_control_request_method;
}
add_header Access-Control-Allow-Origin $cors_origin;
add_header Access-Control-Allow-Credentials $cors_cred;
add_header Access-Control-Allow-Headers $cors_header;
add_header Access-Control-Allow-Methods $cors_method;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
location ~ /.well-known {
allow all;
}
client_max_body_size 50m;
} |
This comment has been minimized.
This comment has been minimized.
Thanks very much guys ! this code plus @RubenHoms 's comment worked like a charm. |
This comment has been minimized.
This comment has been minimized.
Hello guys! We have got working config only with the following trick: `
` if block can be implemented with map |
This comment has been minimized.
This comment has been minimized.
can you expand a bit more in detail? e.g. how to use that map? |
This comment has been minimized.
This comment has been minimized.
I get this error
|
This comment has been minimized.
This comment has been minimized.
Thank you for the snippet and all the comments, it's very useful. @Radiergummi I really like the idea with maps. Is it possible to use wildcard domains there or it could contain only a static list of domain names? @Stanback Why do you use the following block in preflight requests?
Are nginx defaults not enough for this? |
This comment has been minimized.
This comment has been minimized.
Beware: multiple condition blocks are not going to match simultaneously!I can't make multiple if statements to work correctly in my nginx configuration. Have you actually managed to make the both condition blocks apply? |
This comment has been minimized.
This comment has been minimized.
Here's the working config, I've managed to implement. And here's my question on Stack Overflow regarding this issue. |
This comment has been minimized.
This comment has been minimized.
My solution is:
|
This comment has been minimized.
This comment has been minimized.
Your solution more or less worked for me using nginx version 1.12.2 Not sure which version of nginx you were using, but I couldn't run add_headers in my server block, but could in my location block which worked fine. Thanks. |
This comment has been minimized.
This comment has been minimized.
@mPanasiewicz's solution worked perfectly for me (so far). Thank you! |
This comment has been minimized.
This comment has been minimized.
Thanks @mPanasiewicz - your solution is perfect. We ran into many issues with |
This comment has been minimized.
This comment has been minimized.
Another |
This comment has been minimized.
This comment has been minimized.
Thanks for inspiration. Here's what we use with added exposed headers: https://gist.github.com/iki/1247cd182acd1aa3ee4876acb7263def |
This comment has been minimized.
This comment has been minimized.
@mPanasiewicz - your solution works for me. Thanks! |
This comment has been minimized.
This comment has been minimized.
Me too here |
This comment has been minimized.
where should i put this - should it be at the end of /etc/nginx/sites-enabled in the site config