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;
}