5

I have a server that returns a 301 HTTP redirect url which contains an API key. The redirect hits Nginx and in there I need to add an Authorization HTTP Header that contains the value of the API key. I want to then remove the API key from the query parameters that get sent through

I need to translate /google/?search=abcde&apikey=1234&version=1 to /google/?search=abcde&version=1

Code

location /google/ {
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    Host                $http_host;
    proxy_set_header    Authorization       "Bearer $arg_apikey";
    proxy_pass          https://google.com/;
}

I have tried the following, but it doesn't work: Remove parameters within nginx rewrite

location /google/ {
    if ($query_string ~ "^(.*)apikey=(.*)$") {
       rewrite ^(.*)$ $uri? permanent;
    }
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    Host                $http_host;
    proxy_set_header    Authorization       "Bearer $arg_apikey";
    proxy_pass          https://google.com/;
}

Any help would be greatly appreciated!

2
  • 1
    I am not clear on what you are trying to do. Your if block removes the entire query string with a 301 redirect. Are you trying to surgically remove the apikey=1234 part only, and them send the remaining URI upstream with the proxy_pass? Commented Jul 23, 2020 at 13:06
  • @RichardSmith exactly Commented Jul 23, 2020 at 13:24

3 Answers 3

7

One solution is to apply a regular expression to the $request_uri variable (which contains the original request including query string) and capture everything before and after the parameter to be removed.

For example:

map $request_uri $newuri {
    default                                   $request_uri;
    ~^(?<prefix>.*)apikey=[^&]+(?<suffix>.*)$ $prefix$suffix;
}
server {
    ...
    location /google/ {
        resolver ...;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    Host                $http_host;
        proxy_set_header    Authorization       "Bearer $arg_apikey";
        proxy_pass          https://google.com$newuri;
    }
    ...
}

You could probably achieve a similar result with an if block. In this example, the proxy_pass statement is constructed using a map variable. See this document for details.

You will probably need to define a resolver because of the variable in the proxy_pass statement. See this document for details.

Sign up to request clarification or add additional context in comments.

1 Comment

Great, the moment I've got this sorted and working I'll mark this as the answer
0

Use this:

if ($args ~ (.*)&(apikey=[^&]*)(?=&|$)(.*)|^(apikey=[^&]*)(&|$)(.*)) {
    set $args $1$3$6;
    rewrite ^ $uri permanent;
}

in place of your:

if ($query_string ~ "^(.*)apikey=(.*)$") {
       rewrite ^(.*)$ $uri? permanent;
}

Comments

0

The answer above got me most of the way but left some unwanted & and ? chars in the proxied URL. The solution I came up with was:

 map $request_uri $newuri {
    default $request_uri; # param not found
    ~^(?<prefix>.*)\?apiKey=[^&]+$ $prefix; # param is only param
    ~^(?<prefix>.*)apiKey=[^&]+\&(?<suffix>.*)$ $prefix$suffix; # param not last param
    ~^(?<prefix>.*)\&apiKey=[^&]+$ $prefix; # param is last param
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.