NGINX — conditional variables

Marcellin Nshimiyimana
Friday Knowledge
Published in
2 min readJun 11, 2023

This week I learned how to use nginx map directive

Photo by israel palacio on Unsplash

Suppose you have an API server running on https://api.example.com and would like to make sure your API’s get used by https://shop.example.com and https://marketing.example.com.

One way to achieve this is through CORS (cross origin resource sharing), which helps you tell browsers to allow requests to your domains and block all other domains.

You might be tempted to add something like this to your nginx configuration.

And then the browser would complain with an error like this

Access to fetch at 'https://api.example.com/' from origin 'https://marketing.example.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.

In general, if statements are not recommend in nginx, unless they’re the only option.

In our scenario, a map directive can help us create an “allow list” of domains that we want to share our API’s with and provide default value for all other domains.

# api server configuration
http {
# allow list
map $http_origin $allow_origin {
~^https://shop.example.com$ $http_origin;
~^https://marketing.example.com$ $http_origin;

default "";
}

server {
# ...
add_header "Access-Control-Allow-Origin" $allow_origin always;
}
}

This nginx syntax can be compared to a switch statement.

For example, in a Javascript based server (ex: expressjs), you might create the same allow list like shown in the below snippet.

// express server
function generateAllowedOrigin(requestOrigin) {
switch(requestOrigin) {
case 'https://shop.example.com':
case 'https://marketing.example.com':
return requestOrigin;
default:
return '';
}
}

app.use((req, res, next) => {
const http_origin = req.headers.origin;
const allow_origin = generateAllowedOrigin(http_origin);
if(allow_origin) { // expressjs sends headers with empty values, but nginx does not
res.header('Access-Control-Allow-Origin', allow_origin);
}
next();
});

Use cases:

  • Allow CORS for your domains only
  • Allow site access to some countries

Resources:

--

--

Marcellin Nshimiyimana
Friday Knowledge

Always debugging, because problem knowledge equals half the solution!