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

nginx динамический proxy_pass с переменной между перенаправлениями

Nginx proxy_pass с переменными сложно понять. Может ли кто-нибудь объяснить, как я могу реализовать сценарий ниже.

#first call /?proxytohost=http://blahblah.com
#second redirection to /
#third call /home 

location / {
    if ($arg_proxytohost) {
        set $proxytohost $arg_proxytohost;
        rewrite ^.*$ / break;
    }

    proxy_pass https://$proxytohost;   #first call it may recognize, third call definitely it cant

    proxy_intercept_errors on;
    error_page 301 302 307 = @handle_redirects;
}

location @handle_redirects {
    set $saved_redirect_location '$upstream_http_location';
    proxy_set_header  Host $proxy_host;
    proxy_pass $proxytohost$saved_redirect_location;   #this has proxytohost, i dont think it can recognize the variable here
}

РЕДАКТИРОВАТЬ:

Требуется отменить прокси несколько экземпляров, которые являются динамическими (a.blahblah.com, b.blahblah.com и т. Д.). Каждый из этих экземпляров службы имеет несколько перенаправлений, где мне нужно хранить файлы cookie и перенаправлять их (вот почему у меня есть раздел @handle_redirects).

Если я установлю переменную $proxytohost над объявлением местоположения как a.blahblah.com, то он работает должным образом.

Но если я хочу отправить это $proxytohost в качестве динамического аргумента для первого запроса, а затем установить его в переменную, а затем proxy_pass, он не работает.

Например, если предположить, что мой nginx работает в localhost:8080, это то, чего я ожидал

Если я свернусь ниже

http://localhost:8080/?proxytohost=a.blahblah.com?authToken=aksdfkj

он должен перенаправить меня на домашнюю страницу после использования этого токена для аутентификации и перенаправления на домашнюю страницу,

http://localhost:8080/home

в таком случае /home это контент, который подается из https://a.blahblah.com/home.

Это не будет работать.

Если я правильно понимаю, вы хотите использовать прокси для одного и того же хоста при последовательном запросе. Nginx обрабатывает запросы независимо друг от друга. Итак, во втором и третьем запросах, если $arg_proxytohost отсутствует, и используется указанное вами значение по умолчанию.

Я предлагаю использовать для этого файлы cookie. Небольшой пример ниже.

Это должно быть в http {} может быть в conf.d в отдельном файле

map $cookie_p_host $p_host {
    default $cookie_p_host;
    ""      $host;
}

затем у нас есть местоположения, которые поступают на сервер {}

location ~ /proxy/sethost/(?<p_host>.*) { 
    add_header Set-Cookie 'p_host=$p_host;path=/proxy'; 
    add_header Content-type text/html; 
    return 200 'cookie was "$cookie_p_host"<br>now set to "$p_host"'; 
}

location   ~ /proxy(?<p_uri>.*) { 
    resolver         8.8.8.8 ; 
    resolver_timeout 5s; 
    proxy_set_header Host $p_host; 
    proxy_pass       http://$p_host$p_uri; 
}

использование / объяснение:

отображение

Отображение используется, чтобы избежать неприятных операторов if. Если файл cookie установлен, он используется в качестве имени хоста (правильно или нет, мы не проверяем и не заботимся). Если он не установлен (ноль / пустой), мы используем переменную $ host. Можете изменить это на все, что захотите.

первое место

(http: // локальный: 8080 / прокси / sethost / example.com) установит файл cookie с хостом example.com. Все, что находится после / proxy / sethost /, будет считаться именем хоста!

второе место

(http: // локальный: 8080 / прокси) теперь будет прокси на example.com. Добавлен преобразователь для динамического поиска, если его еще нет в конфигурации. Нам нужно установить заголовок Host прокси-запроса на запрошенный и приступить.

Надеюсь это поможет. Редирект вуду - другая тема

Использование переменной в URL-адресе для proxy_pass без преобразователя доступно только в nginx-plus (коммерческая версия)

Добавление преобразователя означает, что вы будете нести ответственность за то, чтобы указать ему DNS, который понимает ваш URL.

Я целую вечность пытался заставить это работать в бесплатной версии:

proxy_pass http://$myvariable:8081;

Это способ nginx сказать «плати мне».

Вы можете изменить директиву if за пределы блока местоположения, и она будет иметь такое же значение.

if ($arg_proxytohost) {
    set $proxytohost $arg_proxytohost;
    rewrite ^.*$ / break;
}
location / {
proxy_pass https://$proxytohost;   #first call it may recognize, third call definitely it cant

proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirects;

}