问题
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