Как добавить заголовок ответа на nginx при использовании proxy_pass?


92

Я хочу добавить настраиваемый заголовок для ответа, полученного от сервера за nginx.

Хотя он add_headerработает для ответов, обработанных nginx, он ничего не делает при proxy_passиспользовании.


Итак, вы передаете запрос прокси-серверу и этот ответ прокси-сервера, и в этот ответ вы хотите добавить свой собственный заголовок, прежде чем он будет отправлен пользователю, верно?
emka86

Ответы:


31

Существует модуль под названием HttpHeadersMoreModule, который дает вам больше контроля над заголовками. Он не поставляется с Nginx и требует дополнительной установки. С его помощью можно сделать что-то вроде этого:

location ... {
  more_set_headers "Server: my_server";
}

Это «установит выходной заголовок сервера на пользовательское значение для любого кода состояния и любого типа контента». Он заменит уже установленные заголовки или добавит их, если они не установлены.


можно ли добавить Secureи HttpOnlyфлаги в ответный cookie ? Однако целевой файл cookie ответа имеет только файл cookie nameи expireатрибуты.
JPaulPunzalan

2
Вам не обязательно нужна библиотека, чтобы иметь возможность изменять или добавлять заголовки ответов, и, в отличие от ответа, получившего наибольшее количество голосов, вы можете переопределить заголовок, вам просто нужно сначала удалить его. Подробности читайте в моем ответе ниже .
Уилт

162

add_headerработает так же хорошо, proxy_passкак и без. Я только что создал конфигурацию, в которой использовал именно эту директиву. Я должен признать, что я тоже боролся с настройкой этого, хотя точно не вспомнил причину.

Прямо сейчас у меня есть рабочая конфигурация, и она содержит (среди прочего) следующее:

server {
    server_name  .myserver.com
    location / {
        proxy_pass  http://mybackend;
        add_header  X-Upstream  $upstream_addr;
    }
}

Раньше nginx 1.7.5 add_header работал только с успешными ответами, в отличие от HttpHeadersMoreModule, упомянутого Себастьяном Гудманом в его ответе .

Начиная с nginx, 1.7.5вы можете использовать ключевое слово alwaysдля включения пользовательских заголовков даже в ответы об ошибках. Например:

add_header X-Upstream $upstream_addr always;

Ограничение: вы не можете переопределить serverзначение заголовка с помощью add_header.


41
Начиная с nginx 1.7.5, вы можете использовать «always» для включения пользовательских заголовков в ответы об ошибках с помощью add_header:add_header X-Upstream $upstream_addr always;
Шейн

В любом случае иметь аналогичную функциональность без раскрытия комбинации IP / порта прокси-сервера? например X-Upstream: 10.10.10.10vs X-Upstream: 53c2d28edefdf501ab7c92e02a0c1687(md5, вероятно, бесполезен для маскировки инфраструктуры, но он передает идею).
Замнутс 03

@zamnuts: передача IP-адреса и номеров портов восходящего потока - это всего лишь пример использования add_headerдирективы. Их совсем не нужно отправлять.
Оливер

@Oliver, я знаю об этом, но я спрашивал об альтернативном индивидуальном / уникальном идентификаторе восходящего потока, отличном от номеров IP / портов, или об их обфускации. Возможно, мой вопрос выходит за рамки, и мне стоит создать новый пост :)
замнутся

@zamnuts: Я бы тоже посоветовал задать новый вопрос :-)
Оливер

25

Как пишет Оливер:

add_headerработает так же хорошо, proxy_passкак и без.

Однако, как пишет Шейн, начиная с Nginx 1.7.5, вы должны пройти always, чтобы приступить add_headerк работе с сообщениями об ошибках, например:

add_header  X-Upstream  $upstream_addr always;

5
Я долго задавался вопросом, почему мои заголовки не показывались, пытаясь переместить их в серверный блок, блок местоположения, ... и вот причина: nginx не добавляет их в ответы об ошибках: F Спасибо
Shautieh

Я тоже :) и, несмотря на этот ответ, это снова случилось со мной на днях. Пришлось пересмотреть свой ответ.
Дмитрий Миньковский


16

Скрыть заголовок ответа, а затем добавить новое значение настраиваемого заголовка

Добавление заголовка add_headerотлично работает с прокси-проходом, но если в ответе есть существующее значение заголовка, оно складывает значения.

Если вы хотите установить или заменить значение заголовка (например, заменить Access-Control-Allow-Origin заголовок, чтобы он соответствовал вашему клиенту, чтобы разрешить совместное использование ресурсов из разных источников), вы можете сделать следующее:

# 1. hide the Access-Control-Allow-Origin from the server response
proxy_hide_header Access-Control-Allow-Origin;
# 2. add a new custom header that allows all * origins instead
add_header Access-Control-Allow-Origin *;

Таким образом, в proxy_hide_headerсочетании с add_headerдает вам возможность устанавливать / заменять значения заголовка ответа.

Подобный ответ можно найти здесь, на ServerFault

ОБНОВИТЬ:

Примечание: proxy_set_header предназначен для установки заголовков запроса перед дальнейшей отправкой запроса, а не для установки заголовков ответа (эти атрибуты конфигурации для заголовков могут немного сбивать с толку).


Спасибо, большая помощь
Lancer.Yan

14

Вы можете попробовать это решение:

В вашем locationблоке, когда вы используете, proxy_passсделайте что-то вроде этого:

location ... {

  add_header yourHeaderName yourValue;
  proxy_pass xxxx://xxx_my_proxy_addr_xxx;

  # Now use this solution:
  proxy_ignore_headers yourHeaderName // but set by proxy

  # Or if above didn't work maybe this:
  proxy_hide_header yourHeaderName // but set by proxy

}

Я не уверен, что это именно то, что вам нужно, но попробуйте немного поработать с этим методом, и, возможно, результат будет соответствовать вашей проблеме.

Также вы можете использовать эту комбинацию:

proxy_hide_header headerSetByProxy;
set $sent_http_header_set_by_proxy yourValue;

6
Мне пришлось использовать этот метод, поскольку nginx добавлял дублирующийся заголовок, а не перезаписывал существующий. location / { proxy_pass http://127.0.0.1:8080/; proxy_hide_header "Access-Control-Allow-Origin"; if ($http_origin ~* "^https://(example.com|www.example.com)$") { add_header Access-Control-Allow-Origin "$http_origin"; } }
ether6
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.