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


26

У меня есть простой обратный прокси-сервер 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.


2
почему передача заголовка хоста не вариант? IMO часть заголовка сделан для таких вещей. если вам нужно передать, какой прокси был использован, вы должны указать дополнительные заголовки.
Jojoo

1
Предположим, у вас есть устаревший сервер, который выполняет виртуальный хостинг, и вы хотите поставить Nginx перед ним, чтобы опубликовать некоторые из этих сервисов в новом домене. Предположим также, что вы не можете (или не хотите) изменять конфигурацию устаревшего сервера. Nginx содержит все инструменты, необходимые для публикации устаревших сервисов на новых сайтах, за исключением проблемы с доменом cookie.
Тобия

Ответы:



5

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

2

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


2
Спасибо за правильный ответ, хотя у меня был плохой опыт работы с ngx_lua в прошлом: плохие утечки памяти. Я думаю, что Nginx нужны некоторые простые примитивы для манипулирования заголовками, использующие его встроенный движок регулярных выражений, если не еще несколько пользовательских инструкций, таких как перезапись домена cookie.
Тобия
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.