我有一个简单的 nginx 反向代理:
server {
server_name external.domain.com;
location / {
proxy_pass http://backend.int/;
}
}
问题是Set-Cookie
响应头包含;Domain=backend.int
,因为后端不知道它正在被反向代理。
我怎样才能让 nginx 重写响应头的内容Set-Cookie
,用;Domain=backend.int
替换;Domain=external.domain.com
?
在这种情况下,传递Host
不变的标题不是一种选择。
Apache httpd已经有此功能一段时间了,请参阅ProxyPassReverseCookieDomain
,但我似乎无法找到在 nginx 中执行相同操作的方法。
答案1
从 1.1.15 开始,添加了 proxy_cookie_domain 选项来解决此问题。
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain
这是具有多个域的示例。您的服务可能可以通过service.foo.com
和访问service.bar.com
,因此您需要相应地在标头中放置foo.com
或 ,而您的后端服务始终在 cookie 标头中放置:bar.com
Set-Cookie
backend_host.com
server {
server_name ~^service\.(?<domain>.+)$;
location / {
proxy_pass http://backend.int/;
proxy_cookie_domain backend_host.com $domain;
}
}
答案2
@shamer 的回答如果有多个响应标头,则运行良好Set-Cookie
,但如果只有一个,则失败。正如 agentzh 在引用线程末尾指出的那样,if type(cookies) ~= "table" then cookies = {cookies} end
需要处理这种情况。
以下是整个事情的经过:
location / {
proxy_pass http://backend.int/;
header_filter_by_lua '
local cookies = ngx.header.set_cookie
if not cookies then return end
if type(cookies) ~= "table" then cookies = {cookies} end
local newcookies = {}
for i, val in ipairs(cookies) do
local newval = string.gsub(val, "([dD]omain)=[%w_-\\\\.]+",
"%1=external.domain.com")
table.insert(newcookies, newval)
end
ngx.header.set_cookie = newcookies
';
}
答案3
这个问题出现在 nginx 邮件列表 [1] 中。在 nginx 中无法直接执行此操作。您必须求助于 ngx_lua 模块 (>=v0.3.1)。
用户“agentzh”有一个在配置文件中内联的示例:
server_name external.domain.com;
location / {
proxy_pass http://backend.int/;
header_filter_by_lua '
local cookies = ngx.header.set_cookie
if not cookies then return end
local newcookies = {}
for i, val in ipairs(cookies) do
local newval = string.gsub(val, "([dD]omain)=[%w_-\\\\.]+",
"%1=external.domain.com")
table.insert(newcookies, newval)
end
ngx.header.set_cookie = newcookies
';
}