Nginx: Reject request if header is not present or wrong

You can use two IF statements either before or in the location block to inspect the headers and then return a 403 error code if it is present. Alternatively, you can use those IF statements to rewrite to a specific location block and deny all in that location:

if ($http_x_custom_header) {
    return 403;
}

Reference:
https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
https://nginx.org/en/docs/http/ngx_http_access_module.html

Adding more detail per comment/request:

if ($http_x_custom_header) {
    return 405;
}

this looks to see if header exists

if you want to check to see if the correct values exist, then you first need to map the correct values to a variable.

map $http_x_header $is_ok {
    default "0";
    Value1  "1";
    Value2  "1";
    Value3  "1";
}

if ($is_ok) {
    return 405; 
}

this first maps the header value to whether or not its ok, then checks to see if the variable is ok.

EDIT: Removed semicolon after map block since this causes an error.


I researched a lot to solve a simple problem: Only allow proxy_pass if request have a specific token in the header. I tried all the answers here and nothing worked how I liked. My final solution is:

location /api {
    proxy_http_version 1.1;

    if ($http_authorization != "Bearer 1234") {
        return 401;
    }

    proxy_pass http://app:3000/;
}

References:

NGINX not equal to

nginx - read custom header from upstream server

https://serverfault.com/questions/490760/nginx-location-exact-match-matches-beyond-arguement

https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/


If you want to allow the HTTP requests only based on some valid header values which are placed inside the response header, one possible way is to use OpenResty tool to apply such restrictions.

The following example allow access to only requests having values "name1" or "name2" for header1:

    header_filter_by_lua '
    local val = ngx.header["header1"]
    if val then
            if (val ~= "name1") and (val ~= "name2") then
                return ngx.exit(400)
            end
    end
    ';