web-dev-qa-db-fra.com

Comment puis-je forcer les utilisateurs à accéder à ma page via HTTPS au lieu de HTTP?

Je souhaite forcer l'accès à une page en tant que page HTTPS (PHP sur Apache). Comment faire cela sans faire en sorte que tout le répertoire nécessite HTTPS? Ou, si vous envoyez un formulaire à une page HTTPS à partir d'une page HTTP, l'envoie-t-il par HTTPS au lieu de HTTP?

Voici mon exemple:

http://www.example.com/some-page.php

Je veux qu'il ne soit accessible que par:

https://www.example.com/some-page.php

Bien sûr, je peux mettre tous les liens vers cette page pointés vers la version HTTPS, mais cela n'empêche pas un imbécile d'y accéder via HTTP à dessein ...

Une chose à laquelle je pensais était de mettre une redirection dans l’en-tête du fichier PHP pour vérifier qu’ils avaient bien accès à la version HTTPS:

if($_SERVER["SCRIPT_URI"] == "http://www.example.com/some-page.php"){
  header('Location: https://www.example.com/some-page.php');
}

Mais ça ne peut pas être le bon chemin, n'est-ce pas?

BTW, s'il vous plaît ne faites pas attention à l'URL. Je sais que s’il s’agissait d’une page comportant un panier d’achat, etc., vous le feriez différemment. Pensez-y comme à une page d'un site qui vend un article à un prix où vous saisissez les informations de votre carte de crédit pour les soumettre à une passerelle de paiement sur un site externe dans le seul but de charger votre carte une fois.

123
Wiki

La façon dont je l'ai fait avant est fondamentalement semblable à ce que vous avez écrit, mais n'a aucune valeur codée en dur:

if ($ _ SERVER ["HTTPS"]! = "on") 
 {
 en-tête ("Emplacement: https: //". $ _SERVER ["HTTP_Host"]. $ _SERVER ["REQUEST_URI"]); 
 sortie();
}
163
Adam Rosenfield

Vous pouvez le faire avec une directive et mod_rewrite sur Apache:

<Location /buyCrap.php>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_Host}%{REQUEST_URI}
</Location>

Vous pouvez rendre l'emplacement plus intelligent au fil du temps en utilisant expressions régulières si vous le souhaitez. 

45
thebigjc

Vous devez forcer le client à demander HTTPS toujours avec les en-têtes HTTP Strict Transport Security (HSTS):

// Use HTTP Strict Transport Security to force client to use secure connections only
$use_sts = true;

// iis sets HTTPS to 'off' for non-SSL requests
if ($use_sts && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
    header('Strict-Transport-Security: max-age=31536000');
} elseif ($use_sts) {
    header('Location: https://'.$_SERVER['HTTP_Host'].$_SERVER['REQUEST_URI'], true, 301);
    // we are in cleartext at the moment, prevent further execution and output
    die();
}

Veuillez noter que HSTS est pris en charge dans la plupart des navigateurs modernes, mais pas universel. Ainsi, la logique ci-dessus redirige manuellement l'utilisateur, quel que soit le support, s'il se retrouve sur HTTP, puis définit l'en-tête HSTS de sorte que les autres demandes des clients soient si possible redirigées par le navigateur.

36
Jacob Swartwood

Je viens de créer un fichier .htaccess et d’ajouter:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_Host}%{REQUEST_URI}

Simple!

14
MatHatrik
// Force HTTPS for security
if($_SERVER["HTTPS"] != "on") {
    $pageURL = "Location: https://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    header($pageURL);
}
9
Jeff

Devait faire quelque chose comme ça quand on courait derrière un équilibreur de charge. Astuce chapeau https://stackoverflow.com/a/16076965/766172

function isSecure() {
    return (
        (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
     || $_SERVER['SERVER_PORT'] == 443
     || (
            (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
         || (!empty($_SERVER['HTTP_X_FORWARDED_SSL'])   && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on')
        )
    );
}

function requireHTTPS() {
    if (!isSecure()) {
        header('Location: https://' . $_SERVER['HTTP_Host'] . $_SERVER['REQUEST_URI'], TRUE, 301);
        exit;
    }
}
7
syvex

http://www.besthostratings.com/articles/force-ssl-htaccess.html

Parfois, vous devrez peut-être vous assurer que l'utilisateur navigue sur votre site via une connexion sécurisée. Un moyen simple de toujours rediriger l'utilisateur vers une connexion sécurisée (https: //) peut être réalisé avec un fichier .htaccess contenant les lignes suivantes:

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

Veuillez noter que le fichier .htaccess doit être situé dans le dossier principal du site Web.

Si vous souhaitez forcer HTTPS pour un dossier particulier, vous pouvez utiliser:

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteCond %{REQUEST_URI} somefolder 
RewriteRule ^(.*)$ https://www.domain.com/somefolder/$1 [R,L]

Le fichier .htaccess doit être placé dans le dossier où vous devez forcer HTTPS.

5
itsazzad

Ok. Maintenant, il y a des tonnes de choses là-dessus, mais personne ne complète vraiment la question "sécurisé" de. Pour moi, il est ridicule d'utiliser quelque chose qui n'est pas sûr.

Sauf si vous l'utilisez comme appât. 

La propagation $ _SERVER peut être modifiée à la volonté de quelqu'un qui sait comment.

En outre, comme l'ont expliqué Sazzad Tushar Khan et thebigjc, vous pouvez également utiliser httaccess pour le faire et de nombreuses réponses le contiennent.

Il suffit d'ajouter:

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

à la fin de ce que vous avez dans votre .httaccess et c'est tout.

Nous ne sommes toujours pas aussi sûrs que nous le pouvons avec ces 2 outils.

Le reste est simple. S'il manque des attributs, c'est-à-dire ...

if(empty($_SERVER["HTTPS"])){ // SOMETHING IS FISHY
}

if(strstr($_SERVER['HTTP_Host'],"mywebsite.com") === FALSE){// Something is FISHY
}


Indiquez également que vous avez mis à jour votre fichier httaccess et que vous vérifiez:

if($_SERVER["HTTPS"] !== "on"){// Something is fishy
}

Il y a beaucoup plus de variables que vous pouvez vérifier c'est-à-dire .. 

Host_URI(s'il y a des attributs statiques à vérifier) ​​

HTTP_USER_AGENT(même session valeurs différentes)

Donc, tout ce que je dis, c'est de ne pas se contenter de l'un ou de l'autre lorsque la réponse réside dans une combinaison.

Pour plus d’informations sur la réécriture de httaccess, voir docs-> http://httpd.Apache.org/docs/2.0/misc/rewriteguide.html

Quelques piles ici -> Forcer SSL/https en utilisant .htaccess et mod_rewrite
et
Obtenir l'URL complète de la page actuelle (PHP)
pour nommer un couple.

5
JSG

Utilisez $_SERVER['HTTPS'] pour indiquer s’il s’agit de SSL , et redirigez-le au bon endroit sinon.

Et rappelez-vous, la page qui affiche le formulaire n'a pas besoin d'être alimentée via HTTPS, c'est l'URL de post-retour qui en a le plus besoin.

Edit: oui, comme indiqué ci-dessous, il est préférable que l'ensemble du processus soit en HTTPS. C'est beaucoup plus rassurant - je soulignais que la publication est la partie la plus critique. En outre, vous devez veiller à ce que tous les cookies soient sécurisés et ne soient envoyés que via SSL. La solution mod_rewrite est également très astucieuse, je l’ai utilisée pour sécuriser de nombreuses applications sur mon propre site Web.

3
DGM

utiliser htaccess:

#if domain has www. and not https://
  RewriteCond %{HTTPS} =off [NC]
  RewriteCond %{HTTP_Host} ^(?i:www+\.+[^.]+\.+[^.]+)$
  RewriteRule ^(.*)$ https://%{HTTP_Host}%{REQUEST_URI} [QSA,L,R=307]

#if domain has not www.
  RewriteCond %{HTTP_Host} ^([^.]+\.+[^.]+)$
  RewriteRule ^(.*)$ https://www.%{HTTP_Host}%{REQUEST_URI} [QSA,L,R=307]
3
siavash bagheri

Si vous utilisez Apache ou quelque chose comme LiteSpeed, qui prend en charge les fichiers .htaccess, procédez comme suit: . Si vous ne possédez pas déjà un fichier .htaccess, vous devez créer un nouveau fichier .htaccess dans votre répertoire racine (généralement où se trouve votre index.php). Ajoutez maintenant ces lignes en tant que premières règles de réécriture dans votre .htaccess:

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

Vous n'avez besoin que de l'instruction "RewriteEngine On" une fois dans votre .htaccess pour toutes les règles de réécriture. Si vous l'avez déjà, copiez simplement les deuxième et troisième lignes.

J'espère que ça aide.

1
Antonio

Utiliser ceci n'est pas suffisant:

if($_SERVER["HTTPS"] != "on")
{
    header("Location: https://" . $_SERVER["HTTP_Host"] . $_SERVER["REQUEST_URI"]);
    exit();
}

Si vous avez un contenu http (comme une source d'image http externe), le navigateur détectera une menace éventuelle. Donc, assurez-vous que tous vos ref et src à l'intérieur de votre code sont https

1
bourax webmaster

Pour ceux qui utilisent IIS en ajoutant cette ligne dans le fichier web.config, cela aidera:

<httpProtocol>
    <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000"/>
    </customHeaders>
</httpProtocol>
<rewrite>
    <rules>
        <rule name="HTTP to HTTPS redirect" stopProcessing="true">
              <match url="(.*)" />
              <conditions>
                 <add input="{HTTPS}" pattern="off" ignoreCase="true" />
              </conditions>
              <action type="Redirect" redirectType="Found" url="https://{HTTP_Host}/{R:1}" />
         </rule>
    </rules>
</rewrite>

Un exemple de fichier complet

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000"/>
             </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions>
                         <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                      </conditions>
                      <action type="Redirect" redirectType="Found" url="https://{HTTP_Host}/{R:1}" />
                 </rule>
            </rules>
       </rewrite>
   </system.webServer>
</configuration>
1
Tschallacka

Ne mélangez pas HTTP et HTTPS sur la même page. Si vous avez une page de formulaire qui est servie via HTTP, je vais être inquiet à propos de la soumission de données - je ne peux pas voir si la soumission passe par HTTPS ou HTTP sans faire un View Source et le rechercher.

Servir le formulaire via HTTPS avec le lien d'envoi ne représente pas un changement important pour l'avantage.

1
JBB

J'ai parcouru de nombreuses solutions avec la vérification de l'état de ($ _SERVER [HTTPS]} _, mais il semble que ce ne soit pas fiable car, parfois, il n'est pas activé ou désactivé, ce qui provoque la boucle interne du script. réorienter.

Voici la solution la plus fiable si votre serveur prend en charge $ _SERVER [SCRIPT_URI]

if (stripos(substr($_SERVER[SCRIPT_URI], 0, 5), "https") === false) {
    header("location:https://$_SERVER[HTTP_Host]$_SERVER[REQUEST_URI]");
    echo "<meta http-equiv='refresh' content='0; url=https://$_SERVER[HTTP_Host]$_SERVER[REQUEST_URI]'>";
    exit;
}

Notez que, selon votre installation, votre serveur peut ne pas prendre en charge $ _SERVER [SCRIPT_URI], mais s'il le fait, il s'agit du meilleur script à utiliser.

Vous pouvez vérifier ici: Pourquoi certaines installations PHP ont-elles $ _SERVER ['SCRIPT_URI'] et d’autres pas

0
Tarik

La manière PHP:

$is_https=false;
if (isset($_SERVER['HTTPS'])) $is_https=$_SERVER['HTTPS'];
if ($is_https !== "on")
{
    header("Location: https://".$_SERVER['HTTP_Host'].$_SERVER['REQUEST_URI']);
    exit(1);
}

La méthode modélisée d'Apache:

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

Vous ne devriez pas pour des raisons de sécurité. Surtout si les cookies sont en jeu ici. Cela vous laisse largement ouvert aux attaques de relecture basées sur les cookies. 

Dans les deux cas, vous devez utiliser les règles de contrôle Apache pour l’accorder.

Ensuite, vous pouvez tester l'activation de HTTPS et rediriger le cas échéant. 

Vous devez rediriger vers la page de paiement uniquement à l'aide d'un FORM POST (aucun get), Et les accès à la page sans POST] doivent être redirigés vers les autres pages. (Cela va attraper les gens qui viennent de sauter à chaud.) 

http://joseph.randomnetworks.com/archives/2004/07/22/redirect-to-ssl-using-apaches-htaccess/

C’est un bon endroit pour commencer, excusez-moi de ne pas fournir plus. Mais vous devriez tout mettre en œuvre via SSL.

C'est trop protecteur, mais au moins vous avez moins de soucis. 

0
Kent Fredric

peut-être que celui-ci pourra vous aider, vous, c'est ce que j'ai fait pour mon site Web, cela fonctionne à merveille:

$protocol = $_SERVER["HTTP_CF_VISITOR"];

if (!strstr($protocol, 'https')){
    header("Location: https://" . $_SERVER["HTTP_Host"] . $_SERVER["REQUEST_URI"]);
    exit();
}
0
Héouais Mongars