PHP — Перенаправление HTTPS на HTTP — бесконечный цикл

#php #apache #redirect #https #http-headers

#php #apache #перенаправление #https #http-заголовки

Вопрос:

Я пытаюсь запретить доступ к определенным страницам на моем сайте через HTTPS и (по какой-либо причине) Я хочу сделать это через PHP, а не через .htaccess.

Вот код, который я использую:

 if ( isset($_SERVER['HTTPS']) amp;amp; $_SERVER['HTTPS'] == 'on' ) {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://mydomain.com");
}
  

Но по какой-то странной причине я застрял в бесконечном цикле и не могу заставить его работать. Когда я проверяю заголовки ответов в firebug, я вижу, что location заголовок установлен на https://mydomain.com вместо http://mydomain.com , что вызывает бесконечный цикл.

РЕДАКТИРОВАТЬ: http://mydomain.com прямой доступ работает.

Также обратите внимание: это работает, если я отправляю их на другую страницу, но не если я отправляю их на ту же страницу. Итак, если я запущу приведенный выше код mydomain.com/somePage.php , а затем попытаюсь получить к нему доступ https://mydomain.com/somePage.php , он будет правильно перенаправлен на домашнюю страницу (без SSL-ed). Только когда я перенаправляю их на ту же страницу с другим протоколом, он игнорирует протокол.

Что я делаю не так?

Комментарии:

1. Это опечатка, что он говорит header("Location: http:// , а не header("Location: https:// … или это то, что на самом деле говорит код?

2. @Dennis: Извините, вы правы. Неправильно прочитано. Я бы поискал другие места в вашем коде, которые вызывают перенаправление с http-> https. У вас есть что-нибудь в httpd.conf/.htaccess? Или даже другой блок PHP в другом месте?

3. Вам нужно isset или будет if (!empty($_SERVER['HTTPS'])) достаточно? Я не уверен, что вам нужно удваивать isset и == 'on' . Если это не https, переменная $ _SERVER[‘HTTPS’] будет пустой, поэтому просто проверка этой единственной переменной на наличие значения должна работать — по крайней мере, это то, что я бы предположил. У меня нет сервера с поддержкой HTTPS для тестирования прямо сейчас.

4. Что, если вы удалите 301 заголовок?

5. Причудливый. Если завтра на это не будет ответа, я протестирую его на рабочем сервере и посмотрю, что произойдет.

Ответ №1:

Оказывается, в моем коде не было ничего плохого. Сервер был просто настроен таким образом, что путался с моими заголовками. Я использую engineHosting.com , и я должен сказать: они были очень полезны. После долгих разговоров с ними, вот что они мне прислали:

Мы смогли разобраться в этом, и, возможно, это (так в оригинале) устранило проблему, но само по себе исправление вызывает другие проблемы. Позвольте мне объяснить.

Наша архитектура не типична для большинства веб-хостингов. Ваша учетная запись фактически размещена на двух брандмауэрах, двух системах предотвращения вторжений, двух балансировщиках нагрузки, также выполняющих роль аппаратного ускорения SSL, подключенных к двум веб-узлам apache и массивному серверному серверу mysql.

Проблема заключалась в том, как мы выполняли ускорение SSL внутри балансировщиков нагрузки. У нас было несколько клиентов, которые хотели определить, когда пользователь обращался к странице, которая предназначалась только для использования с https, но никогда не было обратного желания определить, когда пользователь был на странице, которая должна быть перенаправлена на обычный http. Из-за этого у нас была включена опция в наших балансировщиках нагрузки под названием «только для сайтов SSL с оптимизированным сжатием http wan», которая также переписывает заголовок исходящего местоположения на https, когда запрашивающий URL-адрес уже включен https. Это полезно, когда у вас может быть много ссылок на ресурсы по одному и тому же URL, которые обслуживаются динамически, но случайно записали ссылку как http. Так что это на самом деле функция, а не ошибка (и да, мне тоже не нравится эта фраза).

Чтобы обойти ваш конкретный вариант использования, мы изменили профиль SSL для вашего домена на «сжатие http для обычных / не ssl» настроек виртуального сервера. Вероятно, в прошлом вы не сталкивались с этой проблемой при использовании односерверных веб-решений. Печальным следствием работы в этом режиме является то, что другой вариант использования 30-кратного перенаправления на уровне сервера для перенаправления пользователей с http на https может иметь проблемы в зависимости от того, как реализованы перенаправления. На всякий случай вам следует проверить методы, которые вы будете использовать на своем живом сайте, и сообщить мне, если у вас возникнут какие-либо проблемы.

Комментарии:

1. Хех, эта «особенность» стоила мне утра. Спасибо за публикацию этого.

2. @Populus — вы тоже на engineHosting?

Ответ №2:

Не совсем уверен, но вот пара вещей, которые я отмечаю:

  1. Если ваш .htaccess или конфигурация сервера настроены на использование HTTPS, вы не сможете обойти это на уровне php.

  2. вы оставили косую черту в конце http://mydomain.com что создает подразумеваемое перенаправление. Попробуйте использовать полный фактический путь в местоположении — http://mydomain.com/index.html или http://mydomain.com/index.php например.

Комментарии:

1. Будет ли .htaccess перенаправляться после отправки заголовков из скрипта?

2. 1) Нет. Как я уже сказал в своем вопросе, http://mydomain.com прямой доступ работает нормально. 2) Я запускаю это на домашней странице, я хочу, чтобы они были перенаправлены туда. 3) Что это implied redirect значит?

3. подразумеваемое перенаправление означает, что нет файла с именем «mydomain.com «. Сервер распознает это и добавляет для вас косую черту, затем использует правила из конфигурации для поиска файла каталога по умолчанию. Так работают веб-серверы, и это потенциально несколько шагов перезаписи, которые предоставляют возможность для настройки, которая добавляет https: обратно туда, если это значение по умолчанию для сервера. Лучше быть явным и не рассчитывать на то, что скрытые вещи делают то, что вы ожидаете, особенно когда это не так.

Ответ №3:

У меня есть автономный сервер, на котором работает HTTPS-сайт. Я провел несколько быстрых тестов, и ваш код работает точно так, как ожидалось. Вот мой код (дословно, изменен только домен):

redir.php

 <?php
if ( isset($_SERVER['HTTPS']) amp;amp; $_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.