26

I'd like to add a parameter in the URL in a proxy pass. For example, I want to add an apiKey : &apiKey=tiger
http://mywebsite.com/oneapi?field=22 ---> https://api.somewhere.com/?field=22&apiKey=tiger Do you know a solution ?

Thank's a lot, Gilles.

server {
      listen   80;
      server_name  mywebsite.com;
      location /oneapi{
      proxy_pass         https://api.somewhere.com/;
      }
    }

5 Answers 5

35
location = /oneapi {
  set $args $args&apiKey=tiger;
  proxy_pass https://api.somewhere.com;
}
Sign up to request clarification or add additional context in comments.

5 Comments

If $args is empty you set $args to ?&apiKey=tiger. It's not right.
In facts, I validated too fast your answer and the edited solution worked. In the question $args isn't empty => ?field=22&apiKey=tiger
This does not appear to work when using a location /somepath block (no equals sign). I had to use rewrite ^(.*)$ $1?$args&myParam=value break; instead at the same spot.
great solution, but see my solution if you want it to work when $args is empty
This is not cleanest way. Please take a look mine.
17

The other answers do not work if $args is empty.

This also works if $args is empty.

location /oneapi {
  set $delimeter "";

  if ($is_args) {
    set $delimeter "&";
  }

  set $args "$args${delimeter}apiKey=tiger";

  proxy_pass https://api.somewhere.com/;
}

2 Comments

Thanks alot :D :D
This is not cleanest way. Please take a look mine.
4

github gist https://gist.github.com/anjia0532/da4a17f848468de5a374c860b17607e7

    #set $token "?"; # deprecated

    set $token ""; # declar token is ""(empty str) for original request without args,because $is_args concat any var will be `?`

    if ($is_args) { # if the request has args update token to "&"
        set $token "&";
    }

    location /test {
        set $args "${args}${token}k1=v1&k2=v2"; # update original append custom params with $token
        # if no args $is_args is empty str,else it's "?"
        # http is scheme
        # service is upstream server
        #proxy_pass http://service/$uri$is_args$args; # deprecated remove `/`
        proxy_pass http://service$uri$is_args$args; # proxy pass
    }

    #http://localhost/test?foo=bar ==> http://service/test?foo=bar&k1=v1&k2=v2

    #http://localhost/test/ ==> http://service/test?k1=v1&k2=v2

8 Comments

the answer would be better if you explained the code and the reason for it.
@ADyson sorry, my english is not very good , but i am working on it. I will improve my answer.
Close, but here when $args is empty, http://localhost/test/ will actually redirect to http://service/test??k1=v1&k2=v2 (two integorrations signs), which seems to be caused by nginx turning $is_args to ? when concatenating to another string, even if empty. Removing $is_args from the final statement in turn will cause $args to lack the preceding token when not empty.
if $args is empty,the $token is ? ,so ` set $args "${args}${token}k1=v1&k2=v2"` you'll get empty str+?+custom params. if $args is not empty ,the $token is &, the L8 code is ?old args+&+custom params.
@Mahn the nginx's doc nginx.org/en/docs/http/ngx_http_core_module.html#var_is_args ?” if a request line has arguments, or an empty string otherwise
|
3

Here's a way to add a paramater in nginx when it's unknown whether the original URL had arguments or not (i.e. when you have to account for both ? and &):

location /oneapi {
    set $pretoken "";
    set $posttoken "?";

    if ($is_args) {
        set $pretoken "?";
        set $posttoken "&";
    }

    # Replace apiKey=tiger with your variable here
    set $args "${pretoken}${args}${posttoken}apiKey=tiger"; 

    # Optional: replace proxy_pass with return 302 for redirects
    proxy_pass https://api.somewhere.com$uri$args; 
}

Comments

1

For someone get here. Thanks for https://serverfault.com/questions/912090/how-to-add-parameter-to-nginx-query-string-during-redirect

The cleanest way on 2021 is:

rewrite ^ https://api.somewhere.com$uri?apiKey=tiger permanent;

If a replacement string includes the new request arguments, the previous request arguments are appended after them

proxy_pass way


upstream api {
    server api.somewhere.com;
}

location /oneapi {
    rewrite ^/oneapi/?(.*) /$1?apiKey=tiger break;
    proxy_pass https://api$uri$is_args$args;
}

3 Comments

Redirect & proxy are two different things. Try googling "redirect vs proxy".
@Lukman They can be used together. Try googling "rewrite proxy_pass together".
This is the correct and most flexible way in terms of query parameters

Your Answer

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