使用 Header 过滤代理响应 Headers
Using a Header to Filter Proxied Response Headers
我有一个上游服务器,它经常通过返回 "Set-Cookie" 响应来设置 Cookie header。
我想在上述上游服务器前面有一个 nginx 代理:
Browser => Nginx => Upstream
如果 Browser => Nginx
请求有 header X-No-Cookies: true
我希望 Upstream => Nginx => Browser
的响应不包含 Set-Cookie
响应 header.如果 X-No-Cookies
有任何其他值,我会将 Set-Cookie
响应 header 原封不动地返回。 我无法更改上游服务器的响应 header 行为。
目前我的nginx配置如下,具体注意proxy_hide_header
指令的使用。我还在 X-No-Cookies
响应 header.
中回应了 $proxy_hide_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;
}
}
当我使用 cURL 发出请求时:
curl \
http://example.com/api \
-H 'X-No-Cookies: true' \
-I
我收到以下回复 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
每当 proxy_hide_header
提供一个 nginx 变量作为参数时,它似乎没有任何效果。如果我将变量换成字符串($proxy_hide_header
替换为 "Set-Cookie"
),我会得到所需的行为 - Set-Cookie
响应 header 被省略。
编辑:我已经把这个问题的代码推送到GitHub
多么有趣的挑战!确实,$proxy_hide_header
不接受变量作为其参数,并且不能在 if
块内使用。我们也不能直接在 location
块中使用 $upstream_...
变量,因为它的值还没有计算。最后我找到了解决办法。我们总是隐藏 Set-Cookie
header 然后在需要时重新设置它,值通过 map
表达式计算:
map $http_x_no_cookies $hide_cookies {
default "0";
"true" "1";
}
map $hide_cookies$upstream_http_set_cookie $cookies {
~^0(.*)$ ;
}
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;
}
}
我有一个上游服务器,它经常通过返回 "Set-Cookie" 响应来设置 Cookie header。
我想在上述上游服务器前面有一个 nginx 代理:
Browser => Nginx => Upstream
如果 Browser => Nginx
请求有 header X-No-Cookies: true
我希望 Upstream => Nginx => Browser
的响应不包含 Set-Cookie
响应 header.如果 X-No-Cookies
有任何其他值,我会将 Set-Cookie
响应 header 原封不动地返回。 我无法更改上游服务器的响应 header 行为。
目前我的nginx配置如下,具体注意proxy_hide_header
指令的使用。我还在 X-No-Cookies
响应 header.
$proxy_hide_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;
}
}
当我使用 cURL 发出请求时:
curl \
http://example.com/api \
-H 'X-No-Cookies: true' \
-I
我收到以下回复 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
每当 proxy_hide_header
提供一个 nginx 变量作为参数时,它似乎没有任何效果。如果我将变量换成字符串($proxy_hide_header
替换为 "Set-Cookie"
),我会得到所需的行为 - Set-Cookie
响应 header 被省略。
编辑:我已经把这个问题的代码推送到GitHub
多么有趣的挑战!确实,$proxy_hide_header
不接受变量作为其参数,并且不能在 if
块内使用。我们也不能直接在 location
块中使用 $upstream_...
变量,因为它的值还没有计算。最后我找到了解决办法。我们总是隐藏 Set-Cookie
header 然后在需要时重新设置它,值通过 map
表达式计算:
map $http_x_no_cookies $hide_cookies {
default "0";
"true" "1";
}
map $hide_cookies$upstream_http_set_cookie $cookies {
~^0(.*)$ ;
}
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;
}
}