Ключевое слово - Балансировщик нагрузки
Проблема сводится к тому, что балансировщик нагрузки обрабатывает шифрование / дешифрование 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, когда это необходимо, и доверять пользователям, НЕ перемещающим его назад (в конце концов, это их данные в строке (обычно)).
Надеюсь, это немного поможет.