Я пытаюсь предотвратить доступ к определенным страницам моего сайта через HTTPS, и (по какой-то причине) я хочу сделать это через PHP, а не через .htaccess.
Вот код, который я использую:
if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com");
}
Но по какой-то странной причине я застрял в бесконечном цикле и не могу заставить его работать. Когда я проверяю заголовки ответов в firebug, я вижу, что для заголовка location установлено значение https://mydomain.com вместо http://mydomain.com, что вызывает бесконечный цикл.
EDIT: Прямой доступ к http://mydomain.com работает.
Также обратите внимание: это работает, если я отправляю их на другую страницу, но не если я отправляю их на ту же страницу. Поэтому, если я запущу приведенный выше код в mydomain.com/somePage.php, а затем попытаюсь получить к нему доступ через https://mydomain.com/somePage.php, он будет правильно перенаправлен на домашнюю страницу (без SSL). Только когда я перенаправляю их на ту же страницу с другим протоколом, протокол игнорируется.
Что я делаю неправильно?
Ответ 1 · рейтинг 3 · MegaHit
Оказывается, в моем коде не было ничего плохого. Сервер был просто настроен таким образом, что возился с моими заголовками. Я использую engineHosting.com и должен сказать: они мне очень помогли. После долгих разговоров с ними, вот что они мне прислали:
Мы смогли разобраться в этом, и, возможно, это (sic) устранило проблему, но исправление само по себе вызывает другие проблемы. Позволь мне объяснить.
Наша архитектура не типична для большинства веб-хостов. Ваша учетная запись фактически размещена на двойных брандмауэрах, двойных системах предотвращения вторжений, двойных балансировщиках нагрузки, также выполняющих роль аппаратного ускорения SSL, перед двумя веб-узлами apache и массивным сервером mysql.
Проблема заключалась в том, как мы выполняли ускорение SSL внутри балансировщиков нагрузки. У нас было несколько клиентов, которые хотели определить, когда пользователь заходит на страницу, предназначенную только для использования с https, но никогда не желали обнаружить, когда пользователь находится на странице, которая должна быть перенаправлена на обычный http. . Из-за этого у нас была включена опция в наших балансировщиках нагрузки, называемая HTTP wan оптимизированным сжатием SSL Sites Only, которая также переписывает заголовок исходящего местоположения на https, когда запрашивающий URL-адрес уже был включен https. Это полезно, когда у вас может быть много ссылок на активы по одному и тому же URL-адресу, который обслуживается динамически, но вы случайно написали ссылку как http. Так что на самом деле это фича, а не баг (и да, мне тоже не нравится эта фраза).
Чтобы обойти ваш конкретный вариант использования, мы изменили профиль SSL для вашего домена на HTTP-сжатие для обычных настроек виртуального сервера или без SSL. Вы, вероятно, не сталкивались с этой проблемой в прошлом при использовании односерверных веб-решений. Неблагоприятным последствием работы в этом режиме является то, что другой вариант использования 30-кратной переадресации на уровне сервера для перенаправления пользователей с http на https может иметь проблемы в зависимости от того, как реализована переадресация. Чтобы быть в безопасности, вы должны проверить методы, которые вы будете использовать на своем действующем сайте, и сообщить мне, если у вас возникнут какие-либо проблемы.
Ответ 3 · Nathan Loding
У меня есть собственный сервер, на котором работает сайт HTTPS. Я сделал несколько быстрых тестов, и ваш код работает именно так, как ожидалось. Вот мой код (дословно, с изменением только домена):
redir.php
<?php
if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/redir.php");
exit;
}
if ( !isset($_SERVER['HTTPS']) || !$_SERVER['HTTPS'])
{
echo "IT'S WORKING!";
}
?>
Я бы определенно сказал, как сказал Джаред Фарриш в своем чате, что это проблема с хостом. Что-то в конфигурации их сервера заставляет перенаправить обратно на HTTPS. Я не думаю, что это ошибка PHP. На моем сервере работает PHP 5.3.5 с Apache 2.2.17.