11

The following block

location / {
    if ($http_origin ~* (https?://[^/]*\.example\.com(:[0-9]+)?)) {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
    }
    try_files $uri $uri/ /index.php?$args;
}

… causes a 404 as the above code never reaches the try_files directive, so:

  1. Is this related to the IfIsEvil of nginx?

  2. If it is, then is there some other way to test the http_origin by not using an if statement?

I have tried this with nginx > 1.4 (1.4.6, 1.7, 1.7.8).

Eliran Malka
  • 131
  • 7

1 Answers1

21

I would use map:

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;
    }
    ...
 }
Alexey Ten
  • 7,922
  • 31
  • 35
  • What if the allowed origins need to be different for each server? – Chris Martin Apr 05 '15 at 04:21
  • 3
    Use several `map`s with different variables – Alexey Ten Apr 05 '15 at 10:55
  • I don't think you want several maps. I believe you can just put additional lines in the single map. As you can see in the answer above, there are two lines: one for the default (nginx config defined server) and another for example.com domains. This solution is actually brilliant as you can essentially AllowList a set of domains and nginx will return the Access-Control-Allow-Origin value for the domain that is accessing as long as its in the AllowList. – Peter P. Jul 30 '21 at 06:19