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

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

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

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

Решение 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] 

В то время как решение mod_rewrite Gordon отлично работает для вашего среднего веб-сервера Apache, я испытал переадресацию циклов на серверах за прокси-серверами (например, сайты CloudFlare'd или OpenShift). Следующее решение хорошо работает как для прокси-серверов, так и для непропитанных серверов:

 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] 

Я хотел бы отметить, что 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. # ie http://www.example.com/foo/ to https://www.example.com/foo/ 

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

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

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

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

Простой:

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

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

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

 SSLOptions +StrictRequire SSLRequireSSL 

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

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