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

Я пытаюсь предотвратить доступ к определенным страницам моего сайта через 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). Только когда я перенаправляю их на ту же страницу с другим протоколом, протокол игнорируется.

Что я делаю неправильно?


person MegaHit    schedule 12.10.2011    source источник
comment
Это опечатка, что написано header("Location: http://, а не header("Location: https://... или это то, что на самом деле говорит код?   -  person Nathan Loding    schedule 12.10.2011
comment
@ Деннис: Извините, вы правы. Неверно. Я бы поискал другие места в вашем коде, вызывающие перенаправление с http->https. У вас есть что-то в httpd.conf/.htaccess? Или даже еще один блок PHP в другом месте?   -  person Marc B    schedule 12.10.2011
comment
Вам нужен isset или будет достаточно if (!empty($_SERVER['HTTPS']))? Я не уверен, что вам нужно удваивать isset и == 'on'. Если это не https, переменная $_SERVER['HTTPS'] будет пустой, поэтому должна работать простая проверка этой единственной переменной на наличие значения - по крайней мере, я бы так предположил. У меня сейчас нет сервера с поддержкой HTTPS для тестирования.   -  person Nathan Loding    schedule 12.10.2011
comment
Что, если вы удалите заголовок 301?   -  person Nathan Loding    schedule 12.10.2011
comment
Причудливый. Если завтра не будет ответа на этот вопрос, я проверю его на рабочем сервере и посмотрю, что произойдет.   -  person Nathan Loding    schedule 12.10.2011
comment
Разговор между Джаредом Фарришем и Megahit перенесен в чат.< /б>   -  person Robert Harvey    schedule 12.10.2011
comment
@MegaHit проверьте это примечание php.net/manual/en/reserved.variables .php#71051   -  person M. Suleiman    schedule 12.10.2011
comment
@MegaHit попробуйте добавить exit; после ваших звонков header().   -  person igorw    schedule 12.10.2011


Ответы (3)


Оказывается, в моем коде не было ничего плохого. Сервер был просто настроен таким образом, что возился с моими заголовками. Я использую 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 может иметь проблемы в зависимости от того, как реализована переадресация. Чтобы быть в безопасности, вы должны проверить методы, которые вы будете использовать на своем действующем сайте, и сообщить мне, если у вас возникнут какие-либо проблемы.

person MegaHit    schedule 17.10.2011
comment
Хех, эта функция стоила мне утра. Спасибо, что опубликовали это. - person Populus; 18.10.2013
comment
@Populus - ты тоже на хостинге? - person MegaHit; 31.01.2014

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

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

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

person Devin Ceartas    schedule 12.10.2011
comment
Будет ли .htaccess перенаправлять после отправки заголовков из скрипта? - person Jared Farrish; 12.10.2011
comment
1) Нет. Как я уже сказал в своем вопросе, прямой доступ к http://mydomain.com работает нормально. 2) Я запускаю это на домашней странице, я не хочу, чтобы они были перенаправлены туда. 3) Что означает implied redirect? - person MegaHit; 12.10.2011
comment
подразумеваемая переадресация означает, что файла с именем mydomain.com не существует. Сервер распознает это и добавляет косую черту вместо вас, а затем использует правила из конфигурации для поиска файла каталога по умолчанию. Так работают веб-серверы, и потенциально это несколько шагов перезаписи, которые предоставляют возможность для настройки, которая добавляет https: туда, если это значение по умолчанию для сервера. Лучше быть откровенным и не рассчитывать на то, что скрытые вещи сделают то, что вы ожидаете, особенно когда это не так. - person Devin Ceartas; 12.10.2011

У меня есть собственный сервер, на котором работает сайт 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.

person Nathan Loding    schedule 12.10.2011