Принудительное использование SSL / https с использованием .htaccess и mod_rewrite - PullRequest
221 голосов
/ 09 декабря 2010

Как я могу принудительно использовать SSL / https, используя страницы .htaccess и mod_rewrite, специфичные для PHP.

Ответы [ 11 ]

416 голосов
/ 09 декабря 2010

Для Apache вы можете использовать mod_ssl для принудительного использования SSL с SSLRequireSSL Directive:

Эта директива запрещает доступ, если для текущего соединения не включен 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();
    }
}
49 голосов
/ 03 мая 2016

Я нашел решение mod_rewrite, которое хорошо работает как для прокси, так и для прокси серверов.

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

RewriteEngine On

# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]

# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on

# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
35 голосов
/ 09 декабря 2010

PHP Solution

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

function forceHTTPS(){
  $httpsURL = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  if( count( $_POST )>0 )
    die( 'Page should be accessed with HTTPS, but a POST Submission has been sent here. Adjust the form to point to '.$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, вы можете require() централизованный файл, содержащий эту (и любые другие) пользовательские функции, а затем просто запустить функцию forceHTTPS().

HTACCESS/ mod_rewrite Solution

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

RewriteEngine on

# Check for POST Submission
RewriteCond %{REQUEST_METHOD} !^POST$

# Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

# Forcing HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
9 голосов
/ 18 февраля 2017

Решение на основе перезаписи модов:

Использование следующего кода в 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.

7 голосов
/ 16 мая 2016

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

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

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

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteOptions InheritDownBefore
# This prevents the rule from being overrided by .htaccess files in subdirectories.

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
0 голосов
/ 02 июля 2019

Ни один из других ответов не работал для меня. Моя установка - приложение PHP на AWS Beanstalk с классическим ELB. Подход .htaccess не сработает, поэтому мне пришлось применить правила перенаправления к файлу apache httpd.conf. Например. (из документов AWS):

Серверы Apache: метод файла виртуального хоста (рекомендуется)

  1. Откройте файл конфигурации Apache. Возможные места: /etc/httpd/conf/httpd.conf (Apache 2 / httpd), / etc / apache2 / sites-enabled / (Apache 2.4) или /etc/apache2/apache2.conf (Apache в Ubuntu).

  2. Добавьте правило перезаписи в раздел VirtualHost вашего файла конфигурации, как показано ниже.

    RewriteEngine On RewriteCond% {HTTP: X-Forwarded-Proto} = http RewriteRule. * https://%{HTTP:Host}%{REQUEST_URI} [L, R = постоянный]

  3. Сохраните файл конфигурации Apache

  4. Перезапустите Apache

Смотрите здесь: https://www.youtube.com/watch?v=hvqZV_50GlQ

https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/

0 голосов
/ 20 июля 2018

Просто и Легко, просто добавьте следующее

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
0 голосов
/ 13 сентября 2017

попробуйте этот код, он будет работать для всех версий URL, например

0 голосов
/ 17 июня 2017

для принудительного использования SSL с Apache .htaccess вы можете использовать

SSLOptions +StrictRequire
SSLRequireSSL

для перенаправления приведенный выше ответ правильный

0 голосов
/ 28 января 2017

Простой:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow

замените ваш URL на example.com

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