Как я могу заставить 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 в глубине каталога. Два основных подводных камня:
По умолчанию будут выполняться только правила, содержащиеся в самом глубоком файле .htaccess. Вы должны указать директиву RewriteOptions InheritDownBefore (или аналогичную), чтобы изменить это.
Шаблон применяется к пути к файлу относительно подкаталога, а не верхнего каталога, содержащего файл .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