Как я могу заставить пользователей получать доступ к моей странице через HTTPS вместо HTTP?

120

У меня есть только одна страница, на которую я хочу заставить обращаться как HTTPS-страницу (PHP на Apache). Как мне это сделать, если для всего каталога не требуется HTTPS? Или, если вы отправляете форму на HTTPS-страницу с HTTP-страницы, отправляет ли она ее HTTPS вместо HTTP?

Вот мой пример:

http://www.example.com/some-page.php

Я хочу, чтобы к нему обращались только через:

https://www.example.com/some-page.php

Конечно, я могу поместить все ссылки на эту страницу, указанные в версии HTTPS, но это не мешает доступу к нему через HTTP с целью...

Одна вещь, которую я думал, заключалась в том, чтобы перенести перенаправление в заголовок файла PHP, чтобы убедиться, что они обращаются к версии HTTPS:

if($_SERVER["SCRIPT_URI"] == "http://www.example.com/some-page.php"){
  header('Location: https://www.example.com/some-page.php');
}

Но это не может быть правильным, не так ли?

Кстати, не обращайте внимания на URL. Я знаю, что если бы это была страница, где была корзина для покупок и т.д., Вы бы сделали это по-другому. Подумайте об этом как странице с сайта, который продает один товар за одну цену, когда вы вводите информацию о своей кредитной карте, которая должна быть отправлена ​​на платежный шлюз на внешнем сайте, с одной стороны, для зарядки вашей карты один раз.

Теги:
ssl
https

19 ответов

158

То, как я это делал раньше, в основном похоже на то, что вы написали, но не имеет жестко заданных значений:

if($_SERVER["HTTPS"] != "on")
{
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    exit();
}
  • 14
    Вы забыли вызвать exit (), чтобы гарантировать, что скрипт завершит работу после перенаправления. Я обычно заключаю это в функцию под названием requireSSL (). Я могу это назвать в верхней части любой страницы, которую я хочу зашифровать.
  • 29
    Измените if, чтобы быть (empty($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] !== "on") чтобы исправить уведомления PHP.
Показать ещё 5 комментариев
44

Вы можете сделать это с помощью директивы и mod_rewrite на Apache:

<Location /buyCrap.php>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Location>

Вы могли бы сделать местоположение более умным с течением времени, используя регулярные выражения, если хотите.

  • 6
    Где бы вы положили это? Файл .htaccess?
  • 1
    Разве REQUEST_URI не включает "строку запроса" (например,? Page = 1 & id = 41 и т. Д.)? Это то, что говорится в документации Apache ... Так что, если я попытаюсь получить доступ к site.com/index.php?page=1&id=12, я буду перенаправлен на site.com/index.php
Показать ещё 2 комментария
36

Вы должны заставить клиента всегда запрашивать HTTPS с заголовками HTTP Strict Transport Security (HSTS):

// Use HTTP Strict Transport Security to force client to use secure connections only
$use_sts = true;

// iis sets HTTPS to 'off' for non-SSL requests
if ($use_sts && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
    header('Strict-Transport-Security: max-age=31536000');
} elseif ($use_sts) {
    header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], true, 301);
    // we are in cleartext at the moment, prevent further execution and output
    die();
}

Обратите внимание, что HSTS поддерживается в большинстве современных браузеров, но не универсален. Таким образом, приведенная выше логика вручную перенаправляет пользователя независимо от поддержки, если они заканчиваются на HTTP, а затем устанавливает заголовок HSTS, чтобы, возможно, перенаправить дальнейшие клиентские запросы браузером.

  • 0
    Я удивлен, что ни один из других ответов не включает этот заголовок, он очень важен ... есть ли ловушка для объединения двух из них?
  • 0
    Нет ... вы можете определенно установить этот заголовок, если хотите всегда использовать HTTPS. Это просто избыточно устанавливать до и после перенаправления. Я также изменил свой ответ выше, чтобы более точно объяснить совместимость.
Показать ещё 6 комментариев
11

Я только что создал файл .htaccess и добавил:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Простой!

8
// Force HTTPS for security
if($_SERVER["HTTPS"] != "on") {
    $pageURL = "Location: https://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    header($pageURL);
}
7

Придется делать что-то вроде этого, когда работает за балансировщиком нагрузки. Кончик шляпы https://stackoverflow.com/questions/1175096/how-to-find-out-if-youre-using-https-without-serverhttps

function isSecure() {
    return (
        (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
     || $_SERVER['SERVER_PORT'] == 443
     || (
            (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
         || (!empty($_SERVER['HTTP_X_FORWARDED_SSL'])   && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on')
        )
    );
}

function requireHTTPS() {
    if (!isSecure()) {
        header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], TRUE, 301);
        exit;
    }
}
5

Хорошо. Теперь в этом есть много вещей, но никто не завершает "безопасный" вопрос. Для меня смешно использовать то, что небезопасно.

Если вы не используете его в качестве приманки.

Распространение $ _SERVER может быть изменено по желанию того, кто знает, как это сделать.

Также, как сказал Саззад Тушар Хан и thebigjc, вы также можете использовать httaccess для этого, и здесь есть много ответов.

Просто добавь:

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

до конца того, что у вас есть в вашем.httaccess, и вот что.

Тем не менее мы не настолько безопасны, насколько возможно, с этими двумя инструментами.

Остальное просто. Если отсутствуют атрибуты, то есть...

if(empty($_SERVER["HTTPS"])){ // SOMETHING IS FISHY
}

if(strstr($_SERVER['HTTP_HOST'],"mywebsite.com") === FALSE){// Something is FISHY
}


Также скажите, что вы обновили файл httaccess, и вы проверяете:

if($_SERVER["HTTPS"] !== "on"){// Something is fishy
}

Есть намного больше переменных, которые вы можете проверить, то есть..

HOST_URI (если для проверки есть статические атрибуты)

HTTP_USER_AGENT (одинаковые разные значения сеанса)

Таким образом, все, что я говорю, просто не соглашаются на тот или иной, когда ответ лежит в сочетании.

Более подробную информацию о перезаписи httaccess см. В docs-> http://httpd.apache.org/docs/2.0/misc/rewriteguide.html

Здесь несколько стеков → Force SSL/https с использованием.htaccess и mod_rewrite
а также
Получение полного URL-адреса текущей страницы (PHP)
чтобы назвать пару.

  • 2
    но теперь я получаю следующую ошибку: ERR_TOO_MANY_REDIRECTS . Как это исправить?
5

http://www.besthostratings.com/articles/force-ssl-htaccess.html

Иногда вам может потребоваться убедиться в том, что пользователь просматривает ваш сайт через соединение securte. Простой способ всегда перенаправлять пользователя на безопасное соединение (https://) может быть выполнен с помощью файла .htaccess, содержащего следующие строки:

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

Обратите внимание, что .htaccess должен быть расположен в основной папке веб-сайта.

Если вы хотите принудительно установить HTTPS для определенной папки, вы можете использовать:

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteCond %{REQUEST_URI} somefolder 
RewriteRule ^(.*)$ https://www.domain.com/somefolder/$1 [R,L]

Файл .htaccess должен быть помещен в папку, где необходимо принудительно установить HTTPS.

3

используйте htaccess:

#if domain has www. and not https://
  RewriteCond %{HTTPS} =off [NC]
  RewriteCond %{HTTP_HOST} ^(?i:www+\.+[^.]+\.+[^.]+)$
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=307]

#if domain has not www.
  RewriteCond %{HTTP_HOST} ^([^.]+\.+[^.]+)$
  RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=307]
3

Используйте $_SERVER['HTTPS'], чтобы определить, является ли это SSL и перенаправлять в нужное место, если нет.

И помните, что страница, отображающая форму, не должна передаваться через HTTPS, это URL-адрес обратной связи, который больше всего ему нужен.

Изменить: да, как указано ниже, лучше всего использовать весь процесс в HTTPS. Это гораздо более обнадеживающе - я указывал, что пост является самой важной частью. Кроме того, вам необходимо позаботиться о том, чтобы все файлы cookie были настроены на безопасность, поэтому они будут отправляться только через SSL. Решение mod_rewrite также очень изящно, я использовал его для защиты множества приложений на своем собственном веб-сайте.

  • 0
    Это правда, что сама форма не должна быть https, хотя это хорошая идея для большинства людей, которые этого не знают. Если они собираются отправить форму и заметить, что значок блокировки отсутствует, они могут ошибочно предположить, что форма небезопасна.
  • 1
    @ Grame: кроме того, никто не может быть уверен, что форма будет когда-либо отправлена через https. Вся форма (отображаемая через http) может быть подделкой, отправленной на неизвестный или http-сайт открытым текстом. Https - это не только шифрование, но и аутентификация сервера.
1

Для тех, кто использует IIS, добавление этой строки в web.config поможет:

<httpProtocol>
    <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000"/>
    </customHeaders>
</httpProtocol>
<rewrite>
    <rules>
        <rule name="HTTP to HTTPS redirect" stopProcessing="true">
              <match url="(.*)" />
              <conditions>
                 <add input="{HTTPS}" pattern="off" ignoreCase="true" />
              </conditions>
              <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
         </rule>
    </rules>
</rewrite>

Полный файл примера

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000"/>
             </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions>
                         <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                      </conditions>
                      <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
                 </rule>
            </rules>
       </rewrite>
   </system.webServer>
</configuration>
  • 0
    Вопрос конкретно задается об Apache, а не IIS.
  • 1
    А) его не помеченный Apache. Apache упоминается между кавычками. B) это общий вопрос, который не имеет ничего общего с apache в целом. Это применимо к нескольким php, поддерживающим веб-серверы
1

Использование этого НЕ ДОЛЖНО:

if($_SERVER["HTTPS"] != "on")
{
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    exit();
}

Если у вас есть HTTP-контент (например, внешний источник http-изображения), браузер обнаружит возможную угрозу. Поэтому убедитесь, что все ваши ссылки ref и src внутри вашего кода: https

1

Не смешивайте HTTP и HTTPS на одной странице. Если у вас есть страница формы, которая подается через HTTP, я буду нервничать в отношении отправки данных - я не могу понять, проходит ли передача через HTTPS или HTTP без использования View Source и поиска для нее.

Выполнение формы по HTTPS вместе с ссылкой отправки не является тяжелым изменением для преимущества.

0

возможно, это может помочь вам, что я сделал для своего сайта, он работает как шарм:

$protocol = $_SERVER["HTTP_CF_VISITOR"];

if (!strstr($protocol, 'https')){
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    exit();
}
0

Я прошел через множество решений с проверкой статуса $_SERVER [HTTPS], но похоже, что он не является надежным, потому что иногда он не устанавливается или не включается, не выключается и т.д., вызывая перенаправление script на внутренний цикл.

Вот самое надежное решение, если ваш сервер поддерживает $_ SERVER [SCRIPT_URI]

if (stripos(substr($_SERVER[SCRIPT_URI], 0, 5), "https") === false) {
    header("location:https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
    echo "<meta http-equiv='refresh' content='0; url=https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]'>";
    exit;
}

Обратите внимание, что в зависимости от вашей установки ваш сервер может не поддерживать $_SERVER [SCRIPT_URI], но если это так, это лучший script для использования.

Здесь вы можете проверить: Почему у некоторых установок PHP есть $_SERVER ['SCRIPT_URI'], а другие нет

0

Если вы используете Apache или что-то вроде LiteSpeed, которое поддерживает файлы .htaccess, вы можете сделать следующее. Если у вас еще нет файла .htaccess, вы должны создать новый файл .htaccess в корневом каталоге (обычно там, где находится index.php). Теперь добавьте эти строки в качестве первых правил перезаписи в вашем .htaccess:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Вам нужна только команда "RewriteEngine On" один раз в вашем .htaccess для всех правил перезаписи, поэтому, если вы уже имеете ее, просто скопируйте вторую и третью строки.

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

  • 0
    Это то, что сработало для меня, и то, что я использую в своих собственных скриптах на Zend 2-like Framework - я не понимаю понижения.
  • 0
    Может быть , вы получили downvoted , потому что ответ практически такой же , как этот от @MatHatrik , которая была размещена более чем на год раньше?
0

Не следует из соображений безопасности. Особенно, если в игре играют куки. Это дает вам широкие возможности для атаки на основе файлов cookie.

В любом случае, вы должны использовать правила управления Apache для его настройки.

Затем вы можете проверить, включен ли HTTPS и перенаправлять по мере необходимости, когда это необходимо.

Вы должны перенаправить на страницу оплаты только с помощью ФОРМОВОЙ ПОЧТЫ (без получения) и доступ к странице без POST должен быть направлен обратно на другие страницы. (Это заставит людей просто горячо прыгать.)

http://joseph.randomnetworks.com/archives/2004/07/22/redirect-to-ssl-using-apaches-htaccess/

Хорошее место для начала, извинения за не предоставление большего. Но вы действительно должны засунуть все через SSL.

Это чрезмерно защитное, но по крайней мере у вас меньше забот.

-1

Я использовал этот script и хорошо работает через сайт.

if(empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == "off"){
    $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    enter code hereheader('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $redirect);
    exit();
}
-2
<?php 
// Require https
if ($_SERVER['HTTPS'] != "on") {
    $url = "https://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
    header("Location: $url");
    exit;
}
?>

Это легко.

  • 1
    дублированный ответ

Ещё вопросы

Сообщество Overcoder
Наверх
Меню