4

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!

Werner Raath
  • 1,322
  • 3
  • 16
  • 34
  • 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`? – Richard Smith Jul 23 '20 at 13:06
  • @RichardSmith exactly – Werner Raath Jul 23 '20 at 13:24

2 Answers2

6

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.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
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;
}
John Pick
  • 5,562
  • 31
  • 31