Як переписати доменну частину 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заголовками відповідей, але вона не вдається, якщо є лише одна. Як зазначає агент, що знаходиться в кінці посилальної нитки, 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 потребує декількох простих примітивів для маніпулювання заголовком, використовуючи вбудований механізм regexp, якщо не декілька спеціальних інструкцій, таких як переписування домену файлів cookie.
Тобія
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.