Jak mogę wymusić SSL / https używając .htaccess i strony mod_rewrite specyficznej dla PHP.
Jak mogę wymusić SSL / https używając .htaccess i strony mod_rewrite specyficznej dla PHP.
Odpowiedzi:
W przypadku Apache można użyć mod_ssl
do wymuszenia protokołu SSL za pomocą SSLRequireSSL Directive
:
Niniejsza dyrektywa zabrania dostępu, chyba że dla bieżącego połączenia włączony jest HTTP przez SSL (tj. HTTPS). Jest to bardzo przydatne w wirtualnym hoście lub katalogach z obsługą SSL do obrony przed błędami konfiguracji, które ujawniają elementy, które powinny być chronione. Gdy ta dyrektywa jest obecna, wszystkie żądania są odrzucane, które nie używają protokołu SSL.
Nie spowoduje to jednak przekierowania do https. Aby przekierować, spróbuj wykonać następujące czynności mod_rewrite
w pliku .htaccess
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
lub dowolne z różnych podejść podanych w
Możesz również rozwiązać ten problem z poziomu PHP, jeśli Twój dostawca wyłączył .htaccess (co jest mało prawdopodobne, ponieważ poprosiłeś o to, ale i tak)
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();
}
}
%{HTTP:X-Forwarded-Proto}
lub %{HTTP:X-Real-Port}
zmiennych, aby sprawdzić, czy protokół SSL jest włączony.
RewriteRule <input-pattern> <output-url>
. Tak więc przestrzeń musi tam być, a singiel ^
mówi „dopasuj wszystkie wejściowe adresy URL”.
Znalazłem mod_rewrite
rozwiązanie, które działa dobrze zarówno na serwerach proxy, jak i bez proxy.
Jeśli korzystasz z CloudFlare, AWS Elastic Load Balancing, Heroku, OpenShift lub innego rozwiązania Cloud / PaaS i występują pętle przekierowań z normalnymi przekierowaniami HTTPS, wypróbuj następujący fragment kodu.
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]
Pożyczając bezpośrednio z bardzo wyczerpującej odpowiedzi Gordona, zauważam, że twoje pytanie wspomina o specyfice strony w wymuszaniu połączeń 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>' );
}
}
}
Następnie, jak najbliżej góry tych stron, które chcesz zmusić do połączenia przez PHP, możesz require()
scentralizowany plik zawierający tę (i dowolną inną) funkcję niestandardową, a następnie po prostu uruchomić tę forceHTTPS()
funkcję.
Nie wdrożyłem tego rodzaju rozwiązania osobiście (zwykle używałem rozwiązania PHP, takiego jak powyższe, ze względu na jego prostotę), ale poniższe działania mogą być przynajmniej dobrym początkiem.
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]
RewriteCond %{REQUEST_METHOD} !^POST$
?
RewriteCond %{REQUEST_METHOD} !^POST$
powinna zapobiegać wpływowi tych przekierowań na zgłoszenia POST.
Rozwiązanie oparte na modyfikacji przepisu:
Użycie następującego kodu w htaccess automatycznie przesyła wszystkie żądania http do https.
RewriteEngine on
RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Spowoduje to przekierowanie twoich żądań innych niż www i www http do wersji www https.
Inne rozwiązanie (Apache 2.4 *)
RewriteEngine on
RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Nie działa to na niższych wersjach apache, ponieważ zmienna% {REQUEST_SCHEME} została dodana do mod-rewrite od wersji 2.4.
Chciałbym tylko zauważyć, że Apache ma najgorsze reguły dziedziczenia, gdy używa się wielu plików .htaccess w różnych głębokościach katalogów. Dwie kluczowe pułapki:
RewriteOptions InheritDownBefore
dyrektywę (lub podobną), aby to zmienić. (patrz pytanie)Oznacza to, że zasugerował globalne rozwiązanie na Apache Wiki ma nie działać, jeśli używasz innych plików .htaccess w podkatalogów. Napisałem zmodyfikowaną wersję, która:
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/
Proste i łatwe, wystarczy dodać następujące
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Prosty:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow
zamień swój adres URL na example.com
do wymuszania SSL przy pomocy Apache .htaccess, którego możesz użyć
SSLOptions +StrictRequire
SSLRequireSSL
w przypadku przekierowania powyższa odpowiedź jest poprawna
wypróbuj ten kod, będzie działać dla wszystkich wersji adresów URL, takich jak
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]