Как исправить перенаправление Sinatra https на http под nginx - PullRequest
14 голосов
/ 13 июня 2011

У меня есть приложение Sinatra, работающее в nginx (использующее thin в качестве бэк-прокси), и я использую операторы redirect '/<path>' в Sinatra.Однако когда я захожу на сайт по https, эти перенаправления отправляют меня на http://localhost/<path>, а не на https://localhost/<path>, как они должны.

В настоящее время nginx передает управление худому с помощью этой команды proxy_pass <a href="http://thin">http://thin</a>_cluster, где thin_cluster равно

upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; }

Как это исправить?

Ответы [ 2 ]

22 голосов
/ 16 июня 2011

Чтобы Sinatra правильно собрал URL-адрес, используемый для перенаправлений, он должен иметь возможность определить, использует ли запрос ssl, чтобы перенаправление могло быть выполнено с использованием http или https в зависимости от ситуации.

Очевидно, что реальный вызов thin не использует ssl, так как он обрабатывается интерфейсным веб-сервером, а запрос прокси находится в открытом виде. Поэтому нам нужен способ сообщить Синатре, что он должен обрабатывать запрос как безопасный, даже если он на самом деле не использует ssl.

В конечном итоге код, определяющий, следует ли рассматривать запрос как безопасный, находится в методах Rack::Request#ssl? и Rack::Request#scheme. Методы scheme проверяют хэш env, чтобы определить наличие одной из нескольких записей. Одним из них является HTTP_X_FORWARDED_PROTO, что соответствует HTTP-заголовку X-Forwarded-Proto. Если это установлено, то значение используется в качестве схемы протокола (http или https).

Так что, если мы добавим этот HTTP-заголовок в запрос, когда он будет перенаправлен из nginx на сервер, Sinatra сможет правильно определить, когда перенаправлять на https. В nginx мы можем добавить заголовки к прокси-запросам с помощью proxy_set_header, а схема доступна в переменной $scheme .

Итак, добавив строку

proxy_set_header X-Forwarded-Proto $scheme;

в конфигурацию nginx после строки proxy_pass, чтобы она заработала.

1 голос
/ 15 июня 2011

Вы можете заставить все ссылки перейти на https в слое nginx.в nginx.conf:

server{
   listen 80;
   server_name example.com;
   rewrite    ^(.*) https://$server_name$1 redirect;
}    

Это тоже хорошо, чтобы убедиться, что ваши запросы всегда https

...