{{tag>cors nginx}}
====== Allowing CORS requests ======
In order to allow requests from browser from one domain to another you need to allow CORS either in the webserver config or in the app itself.
For [[https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests|simple requests]] like GET allowing headers should work fine, but for [[https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests|preflighted requests]] you need to first respond with **2xx** status code to a preflight request, indicated by the **OPTIONS** method and then set the headers again.
Example of preflighted request not receiving 2xx response
{{ :wiki:screenshots:2024:cors.png |}}
Below is a config for preflighted and simple requests which will allow requests (e.g. from fetch function in browser console) from **example.org** domain to the domain **example.com**
===== nginx =====
server {
server_name example.com;
http2 on;
listen 443 ssl; # Port to listen to for HTTPS requests.
ssl_*
...
location / {
...
if ($request_method = 'OPTIONS') {
add_header 'X-preflighted' 'true';
add_header 'Access-Control-Allow-Origin' example.org always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
return 204;
}
add_header 'Access-Control-Allow-Origin' example.org always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
...
proxy_pass https://some-upstream;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
# Ensure cookies and headers pass correctly
proxy_pass_request_headers on;
proxy_set_header Cookie $http_cookie;
}
}
If you are also setting a cookie, remember that it can only be set from the same domain i.e. if there's an app running under app.example.org and it sends ''Set-Cookie yummy=fe.example.com'', this won't work. You will get an error like ''Cookie “yummy” has been rejected for invalid domain.''
====== Tested on ======
* nginx/1.27.1
====== See also ======
*[[https://stackoverflow.com/a/65206580/6881647|Allow multiple domains via cors]]
====== References ======
* https://www.baeldung.com/linux/nginx-cross-origin-policy-headers
* https://stackoverflow.com/a/70498101/6881647
* https://stackoverflow.com/questions/50771746/nginx-reverse-proxy-and-access-control-allow-origin-issue