-
-
Save michiel/1064640 to your computer and use it in GitHub Desktop.
# | |
# 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'; | |
} | |
} |
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;
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, Are you sure that your nginx is 1.7.5 or newer?
If 'Access-Control-Allow-Credentials' is set "TRUE"
the wildcard (*) in the Allow-Origin dont work!
Thanks.
It is so useful and helpful for me.
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
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;
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
Here is shorter version of access control allow origin for Nginx that should get you started.
I having problem in this code This giving me error.
I have put this code in location inside /site-enabled/ but its still giving error on http://defaultwallpaper.com Please help.
syntax error. missing closing ' in checking OPTIONS. 'Content-Length should be 'Content-Length'
add_header 'Content-Length 0;
Thanks for the snippet but
Line 15 missing '
, fyi
https://gist.github.com/michiel/1064640/858268f0ddb4bd2f9ccbc416e391a4de4844645a#file-cors-nginx-conf-L15
set $cors_origin "https://your.domain";
if ($http_origin ~* ^(https?://[\w\.\-]+(:\d+)?)/?.*?$ ) {
set $cors_origin $1;
}
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials true;
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;
Access-Control-Allow-Methods
/Access-Control-Allow-Headers
use what you prefer.- this way (as all ways with
http_origin
) requiredOrigin
header to be sent to server. - if no
Origin
or trash values - it will use default (the hardcoded valuehttps://your.domain
)
set $cors_origin "https://your.domain";
If you want a wild card domain, I'd set the default to that. The problem is, the origin header isn't always set from what I'm seeing. Vary seems to fix that.
The always directive just means use it for any status code.
That can be some confusion as not everyone who wants "withCredentials" actually wants anything to do with credentials so the security concern goes poof.
There's another option not included of also falling back to the referrer. It's really hard to find out how if actually works in nginx. Nginx configuration doesn't appear to make use of an ordered map or ordered list and the most prevalent documentation on the matter is confusing.
Once you need to go into if space, you might find yourself really wanting a module for this. If the sample you posted goes into something with another if statement then it can be wiped out if another if matches.
My instinct for security also tells me that you might want to validate the origin header though I have to wonder how far to really go with this. Can the user inject anything malicious? If they try to inject a new line then they'll just be sending another header rather than injecting a response header. I suppose the only thing they might do with something reflecting what's sent is try to exploit some client header handling exploit which seems a bit far fetched (and the use of . doesn't do much to prevent that).
if ($http_origin ~* ^(https?://[\w\.\-]+(:\d+)?)/?.*?$ ) {
isn't even valid nginx syntax. I don't know what regex it's supporting but it looks like it's bailing on valid perl/pcre regex for this line.
I'm facing the following error message. Any idea how to solve it please?
Access to XMLHttpRequest at 'https://localhost:8080/sockjs-node/info?t=1558864429094' from origin 'https://localhost' 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.
Here is my config:
location /sockjs-node/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
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-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://app/sockjs-node;
}
I have also tried with the following in all 3 "if" blocks:
add_header "Access-Control-Allow-Origin" $http_origin;
I get the same error message as above.
I ahve also added the following in all 3 "if" blocks in addition to "$http_origin":
add_header 'Access-Control-Allow-Credentials' 'true';
I get the following error message:
sockjs.js?3600:1605 POST https://localhost:8080/sockjs-node/718/n0jb5hss/xhr_streaming?t=1558864860566 404
Access to XMLHttpRequest at 'https://localhost:8080/sockjs-node/718/n0jb5hss/xhr_streaming?t=1558864860566' from origin 'https://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET https://localhost:8080/sockjs-node/718/2rgh44pm/eventsource 404
On
add_header
, if your server will intentionally throw status code other than200, 201, 204, 206, 301, 302, 303, 304, or 307
(Ex.400
or422
) you should addalways
on each lineSo 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;
thx!
I hope my recent solution help to someone, check this https://gist.github.com/alexjs/4165271#gistcomment-3138623
I'm facing the following error message. Any idea how to solve it please?
Access to XMLHttpRequest at 'https://localhost:8080/sockjs-node/info?t=1558864429094' from origin 'https://localhost' 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.
Here is my config:
location /sockjs-node/ { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; 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-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://app/sockjs-node; }
I have also tried with the following in all 3 "if" blocks:
add_header "Access-Control-Allow-Origin" $http_origin;
I get the same error message as above.
I ahve also added the following in all 3 "if" blocks in addition to "$http_origin":
add_header 'Access-Control-Allow-Credentials' 'true';
I get the following error message:
sockjs.js?3600:1605 POST https://localhost:8080/sockjs-node/718/n0jb5hss/xhr_streaming?t=1558864860566 404
Access to XMLHttpRequest at 'https://localhost:8080/sockjs-node/718/n0jb5hss/xhr_streaming?t=1558864860566' from origin 'https://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET https://localhost:8080/sockjs-node/718/2rgh44pm/eventsource 404
This is fantastic. It helped me solve my issue!
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
would work
Hi,
Is anyone able to assist with my issue. I am seeing that my cookie is coming through in the response headers, but not being saved on the browser. I am only noticing this in production (where I am using Nginx and SSL) and not in development (which is not using a proxy and not using SSL). I am using Express
(Node) and Nginx
on Ubuntu 18.04
My configurations are as follows:
Nginx (/etc/nginx/sites-available/default)
server_name api.myBackendURL.net;
location / {
proxy_pass http://localhost:4000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
Cookie values, using express-session
and cors
const sessionOption: session.SessionOptions = {
store: new RedisStore({
client: redis
}),
name: 'qid',
secret: 'njw32323ndiodqwnlad3',
resave: false,
proxy: process.env.NODE_ENV === 'production',
saveUninitialized: false,
cookie: {
// Values from next examples with-passport
domain: .myFrontendURL.app,
maxAge: 1000 * 60 * 60 * 24 * 91, // 3 month cookie
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 1000),
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
path: '/',
sameSite: 'lax'
}
}
app.use(
cors({
origin: "https://subdomain.myFrontendURL.app",
credentials: true
})
)
Headers in the Response
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://subdomain.myFrontendURL.app,
Connection: keep-alive
Content-Length: 151
Content-Type: application/json; charset=utf-8
Date: Sat, 13 Jun 2020 10:18:28 GMT
ETag: W/"97-gYNuyhWohicUF549wSDDpEE4o3M"
Server: nginx/1.14.0 (Ubuntu)
Set-Cookie: qid=s%3AtP2fO9aX1Lo7uU_dLKOewqC9zxf8B-2P.vXSlE1khTK6Qe6O0lIn7g1WxJ1NIJyFHFoff8Jl1IO0; Path=/; HTTPOnly; Secure; Expires=Fri, 15 Oct 3019 09:47:00 GMT; HttpOnly; Secure; SameSite=Lax
Vary: Origin
X-Powered-By: Express
If it's of any use, the request headers are as follows:
accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 282
content-type: application/json
Host: api.myBackendURL.net
Origin: https://subdomain.myFrontendURL.app
Referer: https://subdomain.myFrontendURL.app/
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
Just to note, sudo nginx -t
returns test is successful
, and I have restarted nginx etc.
So, i've never done anything with Nginx, cors, and have absolutely zero coding knowledge or experience, in a layman's terms, how in the world am i supposed to use any of this? It doesn't seem to work no matter how i do it. I'm using nginx 1.19.2
@DictatorL -- you'll find a file nginx/conf/nginx.conf
in your installation that describes how nginx should accept traffic and route it to your application (here are some pre-canned ones you can use https://www.nginx.com/resources/wiki/start/#pre-canned-configurations). This gist shows you a few different examples of how you might setup CORS by using the add_header
options, the exact one for you will depend on what you're trying to accomplish, you can learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS... although as I pointed out above using a wildcard for the origin is not correct, use this instead:
add_header "Access-Control-Allow-Origin" $http_origin;
@DictatorL -- you'll find a file
nginx/conf/nginx.conf
in your installation that describes how nginx should accept traffic and route it to your application (here are some pre-canned ones you can use https://www.nginx.com/resources/wiki/start/#pre-canned-configurations). This gist shows you a few different examples of how you might setup CORS by using theadd_header
options, the exact one for you will depend on what you're trying to accomplish, you can learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS... although as I pointed out above using a wildcard for the origin is not correct, use this instead:add_header "Access-Control-Allow-Origin" $http_origin;
That worked!
Saved my days. I use:
add_header "Access-Control-Allow-Origin" $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT';
For firefox, i installed this plugin
https://add0n.com/access-control.html?version=0.1.9&type=install
After the nginx config above, I was still getting cors erros.
Just installed this plugin and it works
not working for me, I always get 304 redirects on backend requests
@GromNaN thanks a lot :D
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";
It worked for allhost.my-domain.com
I try this configuration, but it is not working. I have a backend server with my code (laravel app) Do I need to have some configurations?
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 ;)