Come posso forzare SSL / https usando .htaccess e mod_rewrite pagine specifiche in PHP.
Come posso forzare SSL / https usando .htaccess e mod_rewrite pagine specifiche in PHP.
Risposte:
Per Apache, è possibile utilizzare mod_ssl
per forzare SSL con SSLRequireSSL Directive
:
Questa direttiva vieta l'accesso a meno che HTTP su SSL (ovvero HTTPS) non sia abilitato per la connessione corrente. Questo è molto utile all'interno dell'host o delle directory virtuali abilitati per SSL per difendersi da errori di configurazione che espongono oggetti che dovrebbero essere protetti. Quando questa direttiva è presente, vengono negate tutte le richieste che non utilizzano SSL.
Questo non farà comunque un reindirizzamento a https. Per reindirizzare, provare quanto segue con mod_rewrite
nel file .htaccess
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
o uno dei vari approcci forniti a
Puoi anche risolverlo dall'interno di PHP nel caso in cui il tuo provider abbia disabilitato .htaccess (che è improbabile da quando l'hai richiesto, ma comunque)
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}
o %{HTTP:X-Real-Port}
variabili per verificare se SSL è attivato.
RewriteRule <input-pattern> <output-url>
. Pertanto, lo spazio deve essere lì e il singolo ^
dice semplicemente "abbina tutti gli URL di input".
Ho trovato una mod_rewrite
soluzione che funziona bene sia per i server proxy che per quelli non proxy.
Se stai usando CloudFlare, AWS Elastic Load Balancing, Heroku, OpenShift o qualsiasi altra soluzione Cloud / PaaS e stai riscontrando loop di reindirizzamento con reindirizzamenti HTTPS normali, prova invece il frammento seguente.
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]
Prendendo in prestito direttamente dalla risposta molto esaustiva di Gordon, noto che la tua domanda menziona la specificità della pagina nel forzare connessioni 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>' );
}
}
}
Quindi, vicino alla parte superiore di queste pagine che si desidera forzare a connettersi tramite PHP, è possibile require()
un file centralizzato contenente questa (e qualsiasi altra) funzione personalizzata, quindi eseguire semplicemente la forceHTTPS()
funzione.
Non ho implementato personalmente questo tipo di soluzione (ho teso ad usare la soluzione PHP, come quella sopra, per la sua semplicità), ma quanto segue potrebbe essere, almeno, un buon inizio.
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$
dovrebbe impedire che gli invii POST siano interessati da questi reindirizzamenti.
Soluzione basata su riscrittura mod:
L'uso del seguente codice in htaccess inoltra automaticamente tutte le richieste http a https.
RewriteEngine on
RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Questo reindirizzerà le tue richieste http non www e www alla versione www di https.
Un'altra soluzione (Apache 2.4 *)
RewriteEngine on
RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Questo non funziona con le versioni precedenti di apache poiché la variabile% {REQUEST_SCHEME} è stata aggiunta a mod-rewrite dal 2.4.
Vorrei solo sottolineare che Apache ha le peggiori regole di ereditarietà quando si utilizzano più file .htaccess in profondità di directory. Due insidie chiave:
RewriteOptions InheritDownBefore
direttiva (o simile) per modificarla. (vedi domanda)Ciò significa che la soluzione globale suggerita sul Apache Wiki fa non funziona se si utilizza qualsiasi altro file .htaccess nelle sottodirectory. Ho scritto una versione modificata che fa:
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/
Semplice e facile, basta aggiungere quanto segue
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Semplice:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow
sostituisci il tuo URL con example.com
solo per forzare SSL con .htaccess di Apache che puoi usare
SSLOptions +StrictRequire
SSLRequireSSL
per il reindirizzamento la risposta sopra è corretta
prova questo codice, funzionerà con tutte le versioni di URL come
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]