web-dev-qa-db-fra.com

Forcer SSL / https en utilisant .htaccess et mod_rewrite

Comment puis-je forcer à SSL/https en utilisant .htaccess et mod_rewrite page spécifique en PHP.

224
Sanjay Shah

Pour Apache, vous pouvez utiliser mod_ssl pour forcer SSL avec SSLRequireSSL Directive :

Cette directive interdit l'accès sauf si HTTP sur SSL (HTTPS) est activé pour la connexion en cours. Ceci est très pratique dans l'hôte virtuel ou les répertoires virtuels activés pour SSL pour se protéger contre les erreurs de configuration qui exposent des éléments à protéger. Lorsque cette directive est présente, toutes les demandes qui n'utilisent pas SSL sont refusées.

Cela ne fera pas une redirection vers https cependant. Pour rediriger, essayez ce qui suit avec mod_rewrite dans votre fichier .htaccess

_RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_Host}%{REQUEST_URI} [L,R=301]
_

ou l'une des différentes approches données à

Vous pouvez également résoudre ce problème depuis PHP au cas où votre fournisseur aurait désactivé .htaccess (ce qui est peu probable puisque vous l'avez demandé, mais quoi qu'il en soit).

_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();
    }
}
_
420
Gordon

J'ai trouvé une solution mod_rewrite qui fonctionne bien pour les serveurs mandatés ou non.

Si vous utilisez CloudFlare, AWS Elastic Load Balancing, Heroku, OpenShift ou toute autre solution Cloud/PaaS et que vous rencontrez boucles de redirection avec des redirections HTTPS normales, essayez le fragment suivant. au lieu.

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]
50
raphinesse

Solution PHP

Empruntant directement à la réponse très complète de Gordon, je remarque que votre question mentionne le fait d’être spécifique à une page pour imposer des connexions 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>' );
    }
  }
}

Ensuite, à proximité du haut de ces pages que vous souhaitez forcer à vous connecter via PHP, vous pouvez require() un fichier centralisé contenant cette fonction (et d’autres) personnalisées, puis exécutez simplement la forceHTTPS() une fonction.

Solution HTACCESS/mod_rewrite

Je n'ai pas implémenté personnellement ce type de solution (j'ai tendance à utiliser la solution PHP, comme celle ci-dessus, pour sa simplicité), mais voici peut-être au moins un bon début.

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]
36
Luke Stevenson

Solution basée sur la réécriture de mods:

L'utilisation du code suivant dans htaccess transfère automatiquement toutes les demandes http à https.

RewriteEngine on

RewriteCond %{HTTPS}::%{HTTP_Host} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

Cela redirigera vos demandes non-www et www http vers www de https.

Une autre solution (Apache 2.4 *)

RewriteEngine on

RewriteCond %{REQUEST_SCHEME}::%{HTTP_Host} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

Cela ne fonctionne pas sur les versions inférieures d'Apache car la variable% {REQUEST_SCHEME} a été ajoutée à mod-rewrite depuis la version 2.4.

10
starkeen

Je voudrais juste souligner qu'Apache a les pires règles d'héritage lors de l'utilisation de plusieurs fichiers .htaccess sur plusieurs répertoires. Deux pièges clés:

  • Seules les règles contenues dans le fichier .htaccess le plus profond seront exécutées par défaut. Vous devez spécifier la directive RewriteOptions InheritDownBefore (ou similaire) pour changer cela. (voir question)
  • Le modèle est appliqué au chemin du fichier par rapport au sous-répertoire et non au répertoire supérieur contenant le fichier .htaccess avec la règle donnée. (voir discussion)

Cela signifie que la solution globale suggérée sur le Apache Wiki ne fonctionne pas si si vous utilisez un autre fichier .htaccess dans des sous-répertoires. J'ai écrit une version modifiée qui fait:

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/
7
lpd

Ce code fonctionne pour moi

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

Simple et facile, ajoutez juste ce qui suit

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_Host}%{REQUEST_URI} [L,R=301]
0
Saurabh Mistry

Aucune des autres réponses n'a fonctionné pour moi. Ma configuration est une application PHP sur AWS Beanstalk avec un ELB classique. L’approche .htaccess ne fonctionnant pas, j’ai donc dû appliquer les règles de redirection au fichier Apache httpd.conf. Par exemple. (à partir de la documentation AWS):

Serveurs Apache: méthode du fichier hôte virtuel (recommandé)

  1. Ouvrez votre fichier de configuration Apache. Les emplacements possibles incluent /etc/httpd/conf/httpd.conf (Apache 2/httpd),/etc/Apache2/sites-enabled/(Apache 2.4) ou /etc/Apache2/Apache2.conf (Apache sur Ubuntu).

  2. Ajoutez une règle de réécriture à la section VirtualHost de votre fichier de configuration, semblable à la suivante.

    RewriteEngine sur RewriteCond% {HTTP: X-Forwarded-Proto} = http RewriteRule. * https: //% {HTTP: hôte}% {REQUEST_URI} [L, R = permanent]

  3. Enregistrez votre fichier de configuration Apache

  4. Redémarrer Apache

Voir ici: https://www.youtube.com/watch?v=hvqZV_50GlQ

https://aws.Amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/

0
Risteard