2014-05-08 11 views
12

Hintergrund: Website (Beispiel.com), DNS-Setup durch cloudflare pro Plan, bietet dies "flexible ssl" (read here), was bedeutet, dass ssl nur zwischen Client und Cloudflare und nicht zwischen Cloudflare und Server existiert, so dass dedizierte IP nicht benötigt und keine speziellen Setups auf dem Server benötigen. Der Server ist so eingerichtet, dass er keine ssl verwendet (nur eine generische Website), aber die flexible SSL-Funktion von cloudflare kümmert sich um den ssl-Aspekt.PHP https überprüfen mit flexiblen ssl (cloudflare), wie vor?

Sprache: PHP (codeignighter, aber das tut wirklich wichtig)

Ziel: wenn zu Domain "exmple.com/ " Surfen oder "http: // exmple.com/", um eine Variable zu erzeugen "http: // example.com" und beim Browsen zu "https: // example.com/*", um eine Variable "https: // example.com" zu generieren.

Was sollte funktionieren (aber tut):

$root = ''; 
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') 
{ 
    //it doesnt reach here... 
    $root .= 'https://'; 
} 
else 
{ 
    $root .= 'http://'; 
} 
$root .= "".$_SERVER['HTTP_HOST']; 
$root .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']); 

ich es immer tun machen: „//example.com“, aber das tut wirklich das Problem für mich zu lösen. Gedanken? Sollte ich einen Stringvergleich durchführen, um die https-Ness zu bestimmen?

Ich bin sicher, der Grund dafür ist, wenn eine Anfrage den Server (https oder http) erreicht, kommt es über Port 80 und es wird nicht als ssl erkannt, so dass $ _SERVER ['HTTPS'] nicht definiert ist. Ich könnte eine benutzerdefinierte ssl zwischen dem Server und Cloudflare einrichten, wäre aber schöner (weniger Aufwand), wenn ich nur einige regexp verwenden und die URL irgendwie vergleichen könnte.

Ich möchte auch mögliche Probleme und Schwachstellen kennen.

Thanks :)

Antwort

24

Ok, ich werde meine eigene Frage für zukünftige Menschen antworten, die das gleiche Problem hat:

if(!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])){ 
    $root .= $_SERVER['HTTP_X_FORWARDED_PROTO'].'://'; 
} 
else{ 
    $root .= !empty($_SERVER['HTTPS']) ? "https://" : "http://"; 
} 

accross es kam, als ich war Ich schaute genau auf $_SERVER und googelte für HTTP_X_FORWARDED_PROTO herum und brachte mich zu einigen Seiten, die dies bestätigten.

+0

Ich vermute, das funktioniert für Full SSL, aber nicht für Flexible SSL. Meine Antwort kann beide behandeln, aber wenn Sie nur Full SSL verwenden, ist es in Ordnung, diese Antwort zu übernehmen. – Mygod

+0

$ _SERVER ['HTTP_X_FORWARDED_PROTO'] arbeitet für mich – code2be

-1

Haben Sie versucht, die $ _SERVER [ 'SERVER_PORT'] Variable überprüft? Das sollte "80" zurückgeben, wenn es nur eine HTTP-Verbindung ist, oder "443", wenn Sie eine HTTPS-Verbindung verwenden.

So eine Funktion wie dies sollte hoffentlich funktionieren:

function get_http() 
{ 
    if ($_SERVER['SERVER_PORT'] == '443') 
    { 
     return 'https'; 
    } 

    return 'http'; 
} 
+1

Wie bereits erwähnt, kommt die Anfrage über den normalen Port 80 zum Server. Ihre Lösung funktioniert also nicht, und wenn sie funktioniert, würde auch die traditionelle Lösung (auf meinem Post erwähnt) funktionieren. tl; dr; im HTTP- und HTTPS-Verkehr kommt Port als 80, nicht als 443 (wegen der Natur der flexiblen SSL durch cloudflare) – decay

+0

Ah, ich dachte, dass es nur war, dass der $ _SERVER ['HTTPS'] Parameter nicht erschien. Scheint, du hast es schon selbst oben sortiert, der nächste Vorschlag wäre, den Rest der Servervariablen zu überprüfen, da es dort zumindest etwas Nützliches gibt. – Johneh

7

$_SERVER['HTTP_X_FORWARDED_PROTO'] funktioniert nicht für mich. Ich weiß nicht warum. Auf jeden Fall hier ist meine Lösung:

function is_https_buttflare() { 
    return isset($_SERVER['HTTPS']) || 
     ($visitor = json_decode($_SERVER['HTTP_CF_VISITOR'])) && 
      $visitor->scheme == 'https'; 
} 
+0

Arbeitete für mich! Vielen Dank! – insign

0

ich das gleiche Problem gegenüber, wo ich nicht das $ _SERVER [ „HTTPS“] Variable, wenn zu zeigen, bekommen konnte ein var_dump ($ _ SERVER) zu tun. In CloudFlare gibt es drei SSL-Einstellungen (Flexible SSL, Full SSL und Full SSL (Strict). Für Server mit selbstsignierten Zertifikaten wird empfohlen, Full SSL zu verwenden. Nachdem ich meine Einstellungen in Full SSL geändert habe, wird $ _SERVER [ Die Variable "HTTPS"] wurde angezeigt, und $ _SERVER ["SERVER_PORT"] wurde von 80 auf 443 geändert.Jetzt kann ich überprüfen, ob meine Seite HTTPS ist oder nicht viel leichter, wie folgt aus:

public function get_https_status() { 
    return isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on' ? 
     true : false; 
} 

Vor diesen Veränderungen zu entdecken, war ich unter Berufung auf $ _SERVER [ „HTTP_CF_VISITOR“] und das Schema validiert, es geklappt Wenn Sie über die öffentliche IP-Adresse auf die Seite zugreifen, aber wenn Sie lokal auf die Seite zugreifen, also "localhost" als URL, gab es $ _SERVER ["HTTP_CF_VISITOR"] nicht, aber $ _SERVER ["HTTPS"]. .. Mein Problem war, auf die Seite über öffentliche IP-Adresse zuzugreifen, $ _SERVER ["HTTPS"] nicht angezeigt und $ _SERVER ["HTTP_CF_VISITOR"] tat. Und umgekehrt.

0

Ich tat dies für alle Ergebnisse zu überprüfen:

 // check if ssl used on server 
     if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443){ 

      echo '<script>console.log("https")</script>'; 

     //check if ssl used on load balancers such as cloudflare 
     }elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { 

      echo '<script>console.log("https")</script>'; 

     }else{ 

      echo '<script>console.log("http")</script>'; 

     } 
2

Es problemlos auf mich funktioniert. Sie können in jedem Ort verwenden:

function is_ssl_active() { 
    if (isset($_SERVER['HTTP_CF_VISITOR'])) { 
    $cf_visitor = json_decode($_SERVER['HTTP_CF_VISITOR']); 
    if (isset($cf_visitor->scheme) && $cf_visitor->scheme == 'https') { 
     return true; 
    } 
    } else if (isset($_SERVER['HTTPS'])) { 
    return true; 
    } 
    return false; 
} 

Cloudflare setzt einige HTTP-Header wie "CF-Besucher. Click here zu mehr Information.