Назад | Перейти на главную страницу

Как переписать доменную часть Set-Cookie в обратном прокси-сервере nginx?

У меня есть простой обратный прокси-сервер 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.15, для решения этой проблемы была добавлена ​​опция proxy_cookie_domain.

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain

Ответ от @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 
    '; 
}

Этот вопрос возник в списке рассылки 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