如何在 nginx 反向代理中重写 Set-Cookie 的域部分?

如何在 nginx 反向代理中重写 Set-Cookie 的域部分?

我有一个简单的 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.comSet-Cookiebackend_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 
        '; 
    } 

[1]http://nginx.2469901.n2.nabble.com/Rewriting-the-domain-part-of-Set-Cookie-in-a-proxy-pass-td6453554.html

相关内容