Wie kann ich SSL/https mit .htaccess und mod_rewrite seitenspezifisch in PHP erzwingen.
Erzwinge SSL/https mit .htaccess und mod_rewrite
Sanjay Shah
Gordon
Für Apache können Sie verwenden mod_ssl
um SSL mit dem zu erzwingen SSLRequireSSL Directive
:
Diese Anweisung verbietet den Zugriff, es sei denn, HTTP über SSL (dh HTTPS) ist für die aktuelle Verbindung aktiviert. Dies ist sehr praktisch innerhalb des SSL-fähigen virtuellen Hosts oder von Verzeichnissen, um sich vor Konfigurationsfehlern zu schützen, die Dinge offenlegen, die geschützt werden sollten. Wenn diese Anweisung vorhanden ist, werden alle Anfragen abgelehnt, die kein SSL verwenden.
Dies führt jedoch nicht zu einer Umleitung zu https. Um umzuleiten, versuchen Sie Folgendes mit mod_rewrite
in Ihrer .htaccess-Datei
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
oder einer der verschiedenen Ansätze, die unter angegeben sind
Sie können dies auch innerhalb von PHP lösen, falls Ihr Provider .htaccess deaktiviert hat (was unwahrscheinlich ist, da Sie danach gefragt haben, aber trotzdem)
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();
}
}
-
Das ist in unserer Situation großartig, da wir derzeit eine Mischung aus http- und https-Traffic haben. Für unseren Admin-Bereich haben wir einfach das .htaccess-Skript eingefügt, während der Rest der Website http beibehalten wurde.
– Michael J. Calkins
24. September 2014 um 23:11 Uhr
-
Wenn ich die mod_rewrite-Methode verwende, werde ich an https gesendet, aber mit dem Fehler „Die Seite leitet nicht richtig um“.
– Tschechisch
9. Oktober 2014 um 12:00 Uhr
-
Followup: Wenn Sie ähnliche Probleme haben, überprüfen Sie Ihre Server- und HTTP-Variablen. Wenn Ihr Server Proxys verwendet, möchten Sie möglicherweise verwenden
%{HTTP:X-Forwarded-Proto}
oder%{HTTP:X-Real-Port}
Variablen, um zu prüfen, ob SSL aktiviert ist.– Tschechisch
9. Oktober 2014 um 12:47 Uhr
-
Wenn Sie erfahren Schleifen umleiten auf Servern, die hinter Proxys laufen (CloudFlare, Openshift), siehe diese Antwort für eine Lösung, die auch für diesen Fall funktioniert.
– Raphinesse
3. Dezember 2015 um 11:58 Uhr
-
@GTodorov – Das Entfernen des Leerzeichens hat die Umschreibregel für mich verletzt. Nach meinem (begrenzten) Wissen über Rewrite-Regeln ist die Syntax
RewriteRule <input-pattern> <output-url>
. Also Platz muss da sein, und das Single^
sagt nur “alle Eingabe-URLs abgleichen”.– Sphinxxx
30. Juni 2016 um 13:37 Uhr
Raphinesse
Ich habe einen … gefunden mod_rewrite
Lösung, die sowohl für Server mit Proxy als auch ohne Proxy gut funktioniert.
Wenn Sie verwenden CloudFlare, AWS Elastic Load Balancing, Heroku, OpenShift oder jede andere Cloud/PaaS-Lösung und Sie erleben Schleifen umleiten Probieren Sie bei normalen HTTPS-Weiterleitungen stattdessen das folgende Snippet aus.
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]
-
Das ist genial, thx! Aber vielleicht ist es erforderlich, eine Post-Bedingung hinzuzufügen? RewriteCond %{REQUEST_METHOD} !^POST$
– Urgotto
16. September 2017 um 9:40 Uhr
-
@Aleksej Stimmt, dies unterbricht unverschlüsselte POST-Anforderungen. Aber ich denke, das ist eine gute Sache. Auf diese Weise werden die Leute bemerken, dass sie etwas falsch machen. Ich denke, das Beste wäre, sie auf eine Seite umzuleiten, die sie darüber informiert, wie sie Ihren Dienst richtig nutzen können.
– Raphinesse
20. März 2018 um 11:53 Uhr
-
@raphinesse Kennst du die Antwort auf diese Frage: stackoverflow.com/questions/51951082/…
– RRN
21. August 2018 um 14:37 Uhr
PHP-Lösung
In Anlehnung an Gordons sehr umfassende Antwort stelle ich fest, dass Ihre Frage erwähnt, dass sie beim Erzwingen von HTTPS/SSL-Verbindungen seitenspezifisch ist.
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>' );
}
}
}
Dann können Sie so weit oben auf diesen Seiten, dass Sie eine Verbindung über PHP erzwingen möchten require()
eine zentralisierte Datei, die diese (und alle anderen) benutzerdefinierten Funktionen enthält, und führen Sie dann einfach die forceHTTPS()
Funktion.
HTACCESS / mod_rewrite-Lösung
Ich habe diese Art von Lösung nicht persönlich implementiert (ich habe der Einfachheit halber eher die PHP-Lösung wie die obige verwendet), aber das Folgende könnte zumindest ein guter Anfang sein.
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]
-
aus Neugier, warum die
RewriteCond %{REQUEST_METHOD} !^POST$
?– depoulo
29. Juni 2013 um 6:43 Uhr
-
Weil POST-Parameter bei einer Umleitung nicht beibehalten werden. Sie können diese Zeile weglassen, wenn Sie sicherstellen möchten, dass alle POST-Übermittlungen sicher sind (alle ungesicherten POST-Übermittlungen werden ignoriert).
– Lukas Stevenson
30. Juni 2013 um 6:35 Uhr
-
@Lucanos – Wie schreibe ich eine RewriteCond, die beim POST keine Umleitung auf http oder https erzwingt? Mein .htaccess erzwingt HTTPS auf bestimmten Seiten und erzwingt dann HTTP auf den restlichen Seiten. Auf den HTTPS-Seiten gibt es jedoch Formulare, die an meinen Webstamm gesendet werden. Das Formular gibt die Aktions-URL als HTTPS an. Da der Webstamm jedoch keine der Seiten ist, die HTTPS erzwingen sollen, erzwingt mein .htaccess dann eine Umleitung – was bedeutet, dass die POST-Variablen verloren gehen. Wie verhindere ich Weiterleitungen bei POST?
– StackOverflowNeuling
8. Juli 2014 um 19:23 Uhr
-
@StackOverflowNewbie: Die Zeile
RewriteCond %{REQUEST_METHOD} !^POST$
sollte verhindern, dass POST-Übermittlungen von diesen Umleitungen betroffen sind.– Lukas Stevenson
9. Juli 2014 um 6:15 Uhr
-
Ich mag diese PHP-Version. Es ist viel besser, da es einen POST berücksichtigt und besser handhabt, wenn Header bereits gesendet wurden.
– TheStoryCoder
29. Februar 2016 um 10:38 Uhr
Amit Verma
Mod-Rewrite-basierte Lösung:
Mit dem folgenden Code in htaccess werden alle HTTP-Anfragen automatisch an https weitergeleitet.
RewriteEngine on
RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Dadurch wird Ihre umgeleitet Nicht-www und www http-Anfragen an www Version von https.
Andere Lösung (Apache 2.4*)
RewriteEngine on
RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Dies funktioniert nicht bei niedrigeren Versionen von Apache, da die Variable %{REQUEST_SCHEME} seit 2.4 zu mod-rewrite hinzugefügt wurde.
lpd
Ich möchte nur darauf hinweisen, dass Apache hat das Schlechteste Vererbungsregeln bei Verwendung mehrerer .htaccess-Dateien über Verzeichnistiefen hinweg. Zwei wesentliche Fallstricke:
- Standardmäßig werden nur die Regeln ausgeführt, die in der tiefsten .htaccess-Datei enthalten sind. Sie müssen die angeben
RewriteOptions InheritDownBefore
Direktive (oder ähnliches), um dies zu ändern. (siehe Frage) - Das Muster wird auf den Dateipfad relativ zum Unterverzeichnis angewendet und nicht auf das obere Verzeichnis, das die .htaccess-Datei mit der angegebenen Regel enthält. (siehe Diskussion)
Dies bedeutet die vorgeschlagene globale Lösung auf der Apache-Wiki tut nicht funktionieren, wenn Sie andere .htaccess-Dateien in Unterverzeichnissen verwenden. Ich habe eine modifizierte Version geschrieben, die Folgendes tut:
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/
Saurabh Mistry
Einfach und einfach, fügen Sie einfach Folgendes hinzu
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Alexufo
Dieser Code funktioniert bei mir
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]