Использовать SSL/https с помощью .htaccess и mod_rewrite

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

Ответ 1

Для 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();
    }
}

Ответ 2

Я нашел решение 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]

Ответ 3

Решение PHP

Заимствуя непосредственно у Гордона очень полный ответ, я отмечаю, что в вашем вопросе упоминается, что он зависит от страницы при форсировании соединений 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 Решение

Я не реализовал это решение лично (я обычно использовал решение 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]

Ответ 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 через глубины каталогов. Две ключевые проблемы:

  • Только правила, содержащиеся в самом глубоком файле .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/

Ответ 6

Этот код работает для меня

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Ответ 7

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

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

Ответ 8

Ни один из других ответов не работал для меня. Моя установка - приложение 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/

Ответ 9

Простой:

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

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

Ответ 10

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

SSLOptions +StrictRequire
SSLRequireSSL

для перенаправления вышеуказанного ответа правильно

Ответ 11

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

  • website.com
  • www.website.com
  • http://website.com
  • http://www.website.com

    RewriteCond %{HTTPS} off
    RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
    RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]