简体   繁体   中英

How to properly setup nginx Access-Control-Allow-Origin into response header based on the Origin header from the request?

I am looking for a nginx config setup that does setup the Access-Control-Allow-Origin to the value received in the Origin .

It seems that the * method doesn't work with Chrome and the multiple URLs doesn't work with Firefox as it is not allowed by CORS specification.

So far, the only solution is to setup the Access-Control-Allow-Origin to the value received in the origin (yes some validation could be implemented).

The question is how to do this in nginx, preferably without installing additional extensions.

set $allow_origin "https://example.com"
# instead I want to get the value from Origin request header
add_header 'Access-Control-Allow-Origin' $allow_origin;

Using if can sometimes break other config such as try_files . You can end up with unexpected 404s.

Use map instead

map $http_origin $cors_header {
    default "";
    "~^https?://[^/]+\.example\.com(:[0-9]+)?$" "$http_origin";
}

server {
    ...
    location / {
        add_header Access-Control-Allow-Origin $cors_header;
        try_files $uri $uri/ /index.php;
    }
    ...
 }

If is evil

I'm starting to use this myself, and this is the line in my current Nginx configuration:

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

This sets a header to allow the origin of the request as the only allowed origin. So where ever you are coming from is the only place allowed. So it shouldn't be much different than allowing "*" but it looks more specific from the browser's perspective.

Additionally you can use conditional logic in your Nginx config to specify a whitelist of hostnames to allow. Here's an example from https://gist.github.com/Ry4an/6195025

if ($http_origin ~* (whitelist\.address\.one|whitelist\.address\.two)$) {
  add_header Access-Control-Allow-Origin "$http_origin";
}

I plan to try this technique in my own server to whitelist the allowed domains.

Here is a part of a file from conf.f directory where people always describes their virtual hosts of Nginx. $http_origin compares with list of allowed_origins and then in second map block the system decides what will write to "header Access-Control-Allow-Origin" according to allowed list. Here is a part of code.

#cat /etc/nginx/conf.d/somehost.conf

map $http_origin $origin_allowed {
        default 0;
        https://xxxx.yyyy.com 1;
        https://zzz.yyyy.com 1;
}
map $origin_allowed $origin {
        default "";
        1 $http_origin;
}
    
server {
       server_name somehost.com;
    #...[skipped text]
    add_header Access-Control-Allow-Origin $origin always;
    #....[skipped text]
}

I test it om my servers. All works fine. Have a nice day & be healthy, Eugene.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM