Обнаружение HTTPS против HTTP на сервере не отправляет ничего полезного - PullRequest
5 голосов
/ 16 февраля 2009

Так что вроде очень похоже на " Обнаружение запросов https в php ":

Хотите, чтобы https://example.com/pog.php перешел к http://example.com/pog.php или даже наоборот.

Проблемы:

  • Невозможно прочитать что-либо из $ _SERVER ["HTTPS"], так как его там нет
  • Сервер отправляет оба запроса через порт 80, поэтому не может проверить наличие 443 в версии HTTPS
  • apache_request_headers() и apache_response_headers() отправляют обратно одно и то же
  • Не могу ничего сказать загрузчику или ему нужно что-то отправить
  • Данные обратной связи с сервером, выдаваемые страницей при обоих URL-вызовах, в точности совпадают, за исключением идентификатора сеанса. Облом.

Есть ли на странице способы определения, вызывается ли он по SSL или без SSL?

Редактировать : $_SERVER["HTTPS"] нет, включен или нет, независимо от того, просматриваете ли вы сайт через SSL или не-SSL. По какой-то причине хостинг решил обслуживать все HTTPS-запросы в зашифрованном виде, но через порт 80. И, таким образом, $_SERVER["HTTPS"] никогда не включается, нет, просто нет полезных отзывов об этой точке сервера. Так что этот параметр всегда будет пустым.

(И да, это означает, что он помечен, скажем, FF или Chrome для частично недействительного SSL-сертификата. Но эта часть не имеет значения.)

Кроме того, наибольшее, что может быть получено при обнаружении URL-адреса, до точки косой черты. PHP не видит, имеет ли запрос https или http в начале.

Ответы [ 2 ]

23 голосов
/ 16 февраля 2009

Ключевое слово - Балансировщик нагрузки

Проблема сводится к тому, что балансировщик нагрузки обрабатывает шифрование / дешифрование SSL и полностью прозрачен для веб-сервера.

Request:  Client -> 443or80 -> loadbalancer -> 80 -> php
Response: PHP -> 80 -> loadbalancer -> 443or80 -> Client

Реальный вопрос здесь: «У вас есть контроль над конфигурацией балансировщика нагрузки?»


Если вы это сделаете, есть несколько способов справиться с этим. Настройте балансировщик нагрузки, чтобы иметь отдельные определения служб для HTTP и HTTPS. Затем отправьте HTTP-трафик на порт 80 веб-серверов, а HTTPS-трафик на порт 81 веб-серверов. (порт 81 больше не используется).

В apache настройте два разных виртуальных хоста:

<VirtualHost 1.2.3.4:80>
   ServerName foo.com
   SetEnv USING_HTTPS 0
   ...
</VirtualHost>

<VirtualHost 1.2.3.4:81>
   ServerName foo.com
   SetEnv USING_HTTPS 1
   ...
</VirtualHost>

Тогда переменная среды USING_HTTPS будет либо 1 | 0, в зависимости от того, какой виртуальный хост ее подобрал. Это будет доступно в массиве $_SERVER в PHP. Разве это не круто?


Если у вас нет доступа к конфигурации Load Balancer , то все немного сложнее. Не будет способа окончательно узнать, используете ли вы HTTP или HTTPS, потому что HTTP и HTTPS являются протоколами . Они указывают, как подключаться и в каком формате отправлять информацию, но в любом случае вы используете HTTP 1.1 для выполнения запроса. В самом запросе нет информации, чтобы сказать, является ли это HTTP или HTTPS.

Но не унывай. Есть пара идей.

Шестой параметр функции PHP setcookie() может дать клиенту команду отправлять cookie ТОЛЬКО через соединения HTTPS (http://www.php.net/setcookie). Возможно, вы можете установить cookie с этим параметром, а затем проверить его при последующих запросах?

Другой возможностью было бы использование JavaScript для обновления ссылок на каждой странице в зависимости от протокола (добавление параметра GET).

(ни один из вышеперечисленных не будет пуленепробиваемым)

Другим прагматичным вариантом было бы получить ваш SSL на другом домене, например secure.foo.com. Тогда вы можете прибегнуть к трюку VirtualHost выше.


Я знаю, что это не самая простая проблема, потому что я имею дело с ней в течение дня (веб-кластер с балансировкой нагрузки за балансировщиком нагрузки Cisco CSS с модулем SSL).

Наконец, вы всегда можете принять точку зрения, что ваше веб-приложение должно переключаться в режим SSL, когда это необходимо, и доверять пользователям, НЕ перемещающим его назад (в конце концов, это их данные в строке (обычно)).

Надеюсь, это немного поможет.

4 голосов
/ 17 февраля 2009
$ _ SERVER ["HTTPS"] нет, включен или нет, независимо от того, просматриваете ли вы сайт по SSL или без SSL. По какой-то причине хостинг решил обслуживать все HTTPS-запросы в зашифрованном виде, но через порт 80. И, таким образом, $ _SERVER ["HTTPS"] никогда не включается, нет, просто нет полезных отзывов об этой точке сервера. Так что этот параметр всегда будет пустым.

Вы должны убедиться, что у провайдера есть следующая строка в записи VHOST для вашего сайта: SSLOptions +StdEnvVars. Эта строка говорит Apache о включении переменных SSL в среду для ваших скриптов (PHP).

...