У меня есть два места в nginx, где одно перенаправляется на другое. Я хочу сделать следующее:
Первый разрешает прямой доступ в браузере и перенаправляет запрос во второе место. Преобразование второго местоположения позволяет отправлять сообщения, делать прокси-запрос и разрешать только из первого местоположения.
Первый:
location /first/ {
rewrite ^ /second/ permanent;
}
Второй:
location /second/ {
proxy_method POST;
proxy_set_body '{ "arg1": "$arg_arg1", "arg2": "$arg_arg2" }
proxy_pass https://some_api.com/
}
Как я могу проверить второе местоположение, если оно перенаправляется из первого (не прямой доступ в браузере) и показывает какую-то 40-кратную ошибку, если это был прямой доступ?
Пытаюсь использовать директиву internal
, но этот рерайт не попадает в категорию внутренних редиректов.
Перенаправление с помощью скрытия /first/ URL в браузере пользователя
Спасибо заранее
Подождите, возможно, я не понял вашего вопроса, но у вас может быть как 301/302 редирект (новый запрос выдается из браузера пользователя, URL-адрес в адресной строке браузера изменяется), так и внутренний рерайт (без дополнительных запросов, URL-адрес не переодеться). Должно быть очевидно, что защита второго местоположения от прямого доступа с помощью ключевого слова internal
ограничит ваш выбор только вторым (без перенаправления, только внутренняя перезапись).
Иван, спасибо за ответ. Когда я использую rewrite ^ /second/ last;
в первом месте и proxy_pass https://some_api.com;
(без косой черты в конце), он переписывает URL-адрес на /second/
, но показывает ошибку 404 (не пропускайте internal
). Если я использую косую черту в конце proxy_pass https://some_api.com/;
, он оставляет /first/
URL-адрес и делает запрос к прокси-серверу (обычно передает бросок internal
), но мне нужно переписать /second
и передать бросок internal
.
Итак, когда он переписывает внутренне, он не делает новый запрос, и первый URL-адрес не скрывается. Вот поэтому и спрашиваю, может еще какой механизм в nginx.
Речь идет не о nginx, а о протоколе HTTP и поведении пользователя в браузере. Что бы вы ни пытались сделать, я думаю, вы пытаетесь сделать это неправильным способом. Как правило, вам нужно сгенерировать какой-то одноразовый токен в вашем первом месте и использовать его во втором, но это работа веб-приложения, nginx — это просто веб-сервер, а не веб-фреймворк (однако это может быть возможно с помощью третьего партийные модули, такие как lua-nginx-модуль). Если вы хотите сделать это с помощью самого nginx, независимо от того, какое решение вы получите, его можно будет отследить и подделать.
Вот идея в общем:
location /first/ {
# set cookie with an access token
add_header Set-Cookie "my_token=my_super_password; path=/second/" always;
# do not use 301 redirect here or it will be cached by user browser, use 302 only!
rewrite ^ /second/ redirect;
}
location /second/ {
if ($cookie_my_token != "my_super_password") { return 403; }
# clear the token cookie on response
add_header Set-Cookie "my_token=deleted; path=/second/; expires=Thu, 01 Jan 1970 00:00:00 GMT" always;
... rest of configuration here
}
Спасибо за внимание и советы, Иван. Это рабочее решение. Согласен с вами, это работа для веб-приложения, а не для веб-сервера.
Если вы нашли решение работоспособным, вы можете принимать ответить (хотя это не обязательно, это может помочь другим людям увидеть, что решение было проверено и принято).
Вы почти сделали это сами, но вам следует более внимательно прочитать документацию директивы
rewrite
. Флагиpermanent
иredirect
завершают обработку запроса, генерируя перенаправления HTTP 301/302, флагиlast
иbreak
контролируют поток обработки запроса. Используйтеrewrite ^ /second/ last;
в первом блоке локации,internal
во втором. Завершающая косая черта послеsome_api.com
будет считаться URI для передачи,proxy_pass https://some_api.com;
без завершающей косой черты будет передаваться текущий URI запроса (уже переписанный в/second/
).