Web

Принудительное использование SSL/https с помощью .htaccess и mod_rewrite

Как я могу заставить SSL/https использовать .htaccess и mod_rewrite page specific в PHP.

 

Ответ 1

Для Apache вы можете использовать mod_ssl для принудительного использования SSL с помощью директивы SSLRequireSSL. Эта директива запрещает доступ, если для текущего соединения не включен HTTP по SSL (т. е. HTTPS). Это очень удобно внутри виртуального хоста с поддержкой SSL или в каталогах для защиты от ошибок конфигурации, которые открывают то, что должно быть защищено. Когда эта директива присутствует, все запросы, не использующие SSL, отклоняются. Однако это не приведет к перенаправлению на https. Для перенаправления попробуйте следующее с помощью mod_rewrite в файле .htaccess

RewriteEngine On

RewriteCond %{HTTPS} !=on

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

 Вы также можете решить эту проблему PHP в случае, если ваш провайдер отключил .htaccess (что маловероятно, поскольку вы просили об этом):

if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {

    if(!headers_sent()) {

        header("Status: 301 Moved Permanently");

        header(sprintf(

            'Location: https://%s%s',

            $_SERVER['HTTP_HOST'],

            $_SERVER['REQUEST_URI']

        ));

        exit();

    }

}

 

Ответ 2

Я нашел решение mod_rewrite, которое хорошо работает как для проксированных, так и для непроксированных серверов. Если вы используете CloudFlare, AWS Elastic Load Balancing, Heroku, OpenShift или любое другое решение Cloud/PaaS и испытываете зацикливание перенаправления при обычном перенаправлении HTTPS, попробуйте использовать следующий фрагмент.

RewriteEngine On

# Если мы получаем перенаправленный http-запрос от прокси-сервера...

RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]

# ...или обычный старый http запрос непосредственно от клиента

RewriteCond %{HTTP:X-Forwarded-Proto} =""

RewriteCond %{HTTPS} !=on

# Перенаправление на https-версию

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

 

Ответ 3

Решение PHP

Я заметил, что в вашем вопросе упоминается специфичность страницы для принудительного HTTPS/SSL-соединения.

function forceHTTPS(){

  $httpsURL = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

  if( count( $_POST )>0 )

    die( 'Доступ к странице должен осуществляться по HTTPS, но здесь отправлено POST-представление. Настройте форму так, чтобы она указывала на '.$httpsURL );

  if( !isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS']!=='on' ){

    if( !headers_sent() ){

      header( "Status: 301 Moved Permanently" );

      header( "Location: $httpsURL" );

      exit();

    }else{

      die( '<script type="javascript">document.location.href="'.$httpsURL.'";</script>' );

    }

  }

}

Затем в верхней части страниц, которые вы хотите заставить подключаться через PHP, вы можете потребовать централизованный файл, содержащий эту (и любые другие) пользовательские функции, а затем просто запустить функцию forceHTTPS().

Решение HTACCESS / mod_rewrite

Я лично не реализовывал подобное решение (я склонялся к использованию PHP-решения, как описано выше, из-за его простоты), но следующее может быть, по крайней мере, хорошим началом.

RewriteEngine on

# Проверка представления POST

RewriteCond %{REQUEST_METHOD} !^POST$

# Принудительное использование HTTPS

RewriteCond %{HTTPS} !=on [OR]

RewriteCond %{SERVER_PORT} 80

# Страницы для подачи заявки

RewriteCond %{REQUEST_URI} ^something_secure [OR]

RewriteCond %{REQUEST_URI} ^something_else_secure

RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

# Принудительный HTTP

RewriteCond %{HTTPS} =on [OR]

RewriteCond %{SERVER_PORT} 443

# Страницы для подачи заявки

RewriteCond %{REQUEST_URI} ^что-то_другое_публичное

RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

 

Ответ 4

Решение на основе Mod-rewrite. Использование следующего кода в htaccess автоматически перенаправляет все http-запросы на https.

RewriteEngine on

RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$

RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

 Это перенаправит ваши не-www и www http запросы на www версию https. Другое решение (Apache 2.4*)

RewriteEngine on

RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$

RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

 Это не работает на более низких версиях apache, так как переменная %{REQUEST_SCHEME} была добавлена в mod-rewrite начиная с версии 2.4.

 

Ответ 5

Я хотел бы отметить, что Apache имеет наихудшие правила наследования при использовании нескольких файлов .htaccess в глубине каталога. Два основных подводных камня:

  1. По умолчанию будут выполняться только правила, содержащиеся в самом глубоком файле .htaccess. Вы должны указать директиву RewriteOptions InheritDownBefore (или аналогичную), чтобы изменить это. 

  2. Шаблон применяется к пути к файлу относительно подкаталога, а не верхнего каталога, содержащего файл .htaccess с заданным правилом. 

Это означает, что предложенное глобальное решение на Apache Wiki не работает, если вы используете любые другие файлы .htaccess в подкаталогах. Я написал модифицированную версию, которая работает:

RewriteEngine On

# Это позволит включить возможности Rewrite

RewriteOptions InheritDownBefore

# Это предотвращает переопределение правила файлами .htaccess в подкаталогах.

RewriteCond %{HTTPS} !=on

# Здесь проверяется, что соединение не является HTTPS.

RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,R,L]

# Это правило перенаправит пользователей с их первоначального местоположения на то же место, но с использованием HTTPS.

# то есть  http://www.example.com/foo/ to https://www.example.com/foo/

 

 

Схожие статьи

Web

Как получить содержимое POST на php?

Web

Передача переменных JavaScript в PHP?

Что такое Флаттер от Google, как им пользоваться и зачем он создан?
Web

Что такое Флаттер от Google, как им пользоваться и зачем он создан?

Web

Потеря PHP сеанса после перенаправления