Using a Header to Filter Proxied Response Headers

孤者浪人 提交于 2019-12-19 11:53:46

问题


I have an upstream server that often sets Cookie(s) by returning the "Set-Cookie" response header.

I would like to have an nginx proxy in front of said upstream server:

Browser => Nginx => Upstream

If the Browser => Nginx request had the header X-No-Cookies: true I'd like the response from Upstream => Nginx => Browser not to contain the Set-Cookie response header. If X-No-Cookies had any other value, I'd lie the Set-Cookie response header to be returned unaltered. I'm not able to change the response header behavior of the upstream server.

Currently my nginx config is as follows, pay specific attention to the use of the proxy_hide_header directive. I've also echoed the $proxy_hide_header variable in the X-No-Cookies response header.

map $http_x_no_cookies $proxy_hide_header {
  default "";
  "true"  "Set-Cookie";
}

# Homepage
server {
  listen 80;
  server_name example.com;

  location /api {
    proxy_pass        https://example.com/api;
    proxy_hide_header $proxy_hide_header;
    add_header        "X-No-Cookies" $proxy_hide_header;
  }
}

When I make a request with cURL:

curl \
  http://example.com/api \
  -H 'X-No-Cookies: true' \
  -I

I get the following response headers:

Server: nginx/1.12.2
Date: Thu, 13 Dec 2018 02:26:41 GMT
Content-Type: application/json
Content-Length: 2255
Connection: keep-alive
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept,Authorization
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Expose-Headers: Content-Length
Set-Cookie: foo=bar; Max-Age=2592000; Expires=Sat, 12 Jan 2019 02:26:41 GMT; Path=/; Domain=example.com; Secure
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-No-Cookies: Set-Cookie

Whenever the proxy_hide_header is provided an nginx variable as an argument it seems to have no effect. If I swap the variable for a string ($proxy_hide_header substituted for "Set-Cookie") I get the desired behaviour - the Set-Cookie response header is omitted.

Edit: I've pushed the code for this question to GitHub

  • My original (non-working) implementation is here
  • Ivan Shatsky's solution is here

回答1:


What an interesting challenge! Truly, $proxy_hide_header does not accept variables as its parameter and cannot be used inside an if blocks. Also we cannot use $upstream_... variables directly inside a location block because its values are not evaluated yet. Finally I found a solution. We always hide Set-Cookie header and then set it again if needed, values calculating through map expressions:

map $http_x_no_cookies $hide_cookies {
    default "0";
    "true"  "1";
}

map $hide_cookies$upstream_http_set_cookie $cookies {
    ~^0(.*)$ $1;
}

upstream backend {
    server example.com;
}

server {
    listen 80;
    server_name example.com;

    location /api {
        proxy_pass        https://backend/api;
        proxy_hide_header Set-Cookie;
        add_header Set-Cookie $cookies;
    }
}


来源:https://stackoverflow.com/questions/53754229/using-a-header-to-filter-proxied-response-headers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!