2016-11-01 2 views
2

Vorwort

Diese Antworten haben mir nicht helfen, aber sie könnten jemanden, der über diese Frage stolpert helfen:Session fehlt, außer wenn ich eine „nicht sichere“ Cookie


Die Frage

Ich habe zu brechen Meine Erdnuss ist den ganzen Tag über gestrandet und ich kann mich nicht glücklich schätzen, wenn es darum geht, mich in meine eigene Anwendung einzuloggen. Alle hilfreichen Antworten zu SO sind in etwa wie folgt: "Hast du eine Sitzung begonnen?" - Was ich habe.

Wenn ich mich einlogge, gibt das Skript mit dem Status korrekt und gibt mir die folgenden Header:

"Expires: Thu, 19 Nov 1981 08:52:00 GMT", 
"Cache-Control: no-store, no-cache, must-revalidate", 
"Pragma: no-cache", 
"Set-Cookie: ADMSESSION=f27n49icvbv0bjfgh4bffojgs0; path=\/; secure; HttpOnly" 

Ich kann bestätigen, dass dieses Cookie in meinem Browser tatsächlich vorhanden ist, und das Cookie beendet wird nur, wenn die Der Browser wird geschlossen.

Jetzt ist das, wo die Magie nicht passiert. Nach Erhalt des "Go Ahead" -Status vom Server aktualisiert das lokale Skript die Seite, um die echte Back-End-Sitzung zu laden. Zumindest sollte es das tun. Das Skript lädt die Seite neu und ich werde erneut von derselben Anmeldeaufforderung begrüßt. Es treibt mich die Wand hoch.

Nach sorgfältiger Prüfung stellte ich fest, dass mein Sitzungscookie überhaupt nicht verwendet wurde, also habe ich ihn in einen unsicheren Cookie umgewandelt (Set-Cookie: ADMSESSION=f27n49icvbv0bjfgh4bffojgs0). Diese scheint zu arbeiten auf allen Seiten, die den Benutzer angemeldet sein müssen ... Allerdings funktioniert es nur auf diesen Seiten und nicht auf der Anmeldeseite. Ich kann mich nicht damit herumschlagen, da alles in der Logik der gleichen Trajektorie folgt und keine Header gesendet werden, bis der Server mit der Verarbeitung fertig ist.


Relevante Schnipsel

Hier sind einige relevante Schnipsel, die die Logik-Flow und Art und Weise der Einstellung und bekommen die Sitzung erläutern. Einige Informationen wurden aus Sicherheitsgründen gelöscht.

<?php // index.php 

    /** 
    * just print everything, I want to know when, where, and how 
    * the brown sticky stuff starts hitting the ceiling whirly device. 
    */ 
    error_reporting(E_ALL); 
    ini_set("display_startup_errors", 1); 
    ini_set("display_errors", 1); 

    require_once "path/to/my/config.php"; 

    // session and login manager 
    require_once "path/to/my/SecurityService.php"; 

    use \Namespace\Of\My\SecurityService as LoginManager; 

    // argument false: don't log activity on this page. 
    $loginManager = new LoginManager(false); 

    // start session 
    $loginManager->secureSessionStart(); 

    // @fixme: secureSessionCheck is not fired!? 
    if($loginManager->secureSessionCheck()) { 
     print file_get_contents("path/to/views/main.html"); 
    } else { 
     print file_get_contents("path/to/views/login.html"); 
    } 

<?php // SecurityService.php:51-75 (inside login method called via POST) 
     if($this->verify($credentials["passwordHash"])) { 
      if($this->logger !== null) 
       $this->logger->write("info", "successful login from {$_SERVER["REMOTE_ADDR"]}."); 

      $_SESSION["browser"] = $_SERVER["HTTP_USER_AGENT"]; 
      // redacted 
      // redacted 
      $_SESSION["visitor"] = $_SERVER["REMOTE_ADDR"]; 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 

      session_commit(); 

      if($this->logger !== null) 
       $this->logger->write("info", "User ({$_SESSION["email"]}) created in session (" . session_id() . ")."); 

      return true; 
     } 

<?php // SecurityService.php:92-127 
    /** 
    * secureSessionStart 
    * Starts a session in a secure way 
    */ 
    public function secureSessionStart() { 
     if(ini_set("session.use_only_cookies", 1) === FALSE) { 
      if($this->logger !== null) 
       $this->logger->write("error", "PHP ini is configured incorrectly. (session.use_only_cookies)"); 

      return; 
     } 

     switch(session_status()) { 
      case PHP_SESSION_DISABLED: 
       if($this->logger !== null) 
        $this->logger->write("error", "Sessions are disabled. Unable to log this user in!"); 
       return; 
      case PHP_SESSION_NONE: 
       session_set_cookie_params(0, "/", "", true, true); 
       session_name("ADMSESSION"); 
       session_start(); 
       break; 
      case PHP_SESSION_ACTIVE: 
       session_set_cookie_params(0, "/", "", true, true); 
       session_name("ADMSESSION"); 
       session_start(); 

       $oldID = session_id(); 

       session_regenerate_id(true); 

       if($this->logger !== null) 
        $this->logger->write("info", "Session ({$oldID}) moved to (" . session_id() . ")."); 
       break; 
     } 
    } 

<?php // SecurityService.php:118-189 
    /** 
    * secureSessionCheck 
    * Checks the current session if it"s valid with current data 
    * 
    * @return boolean 
    */ 
    public function secureSessionCheck() { 
     if(!isset($_SESSION)) { 
      if($this->logger !== null) 
       $this->logger->write("error", "Session is not set."); 

      return false; 
     } 

     if(!isset($_SESSION[/* redacted */]) || !isset($_SESSION["browser"]) || !isset($_SESSION["visitor"])) { 
      if($this->logger !== null) 
       $this->logger->write("error", "Session (" . session_id() . ") does not contain a valid administrator."); 

      return false; 
     } 

     if($_SESSION["browser"] !== $_SERVER["HTTP_USER_AGENT"]) { 
      if($this->logger !== null) 
       $this->logger->write("warning", "Session (" . session_id() . ") browser conflicts with current user agent."); 

      return false; 
     } 

     if($_SESSION["visitor"] !== $_SERVER["REMOTE_ADDR"]) { 
      if($this->logger !== null) 
       $this->logger->write("warning", "Session (" . session_id() . ") visitor conflicts with current visitor IP."); 

      return false; 
     } 

     // redacted (gets $this->data) 

     if(!isset($this->data)) { 
      if($this->logger !== null) 
       $this->logger->write("error", "Data object is not set."); 

      return false; 
     } 

     if(!isset($this->data->/* redacted */) || !isset($this->data->/* redacted */) || !isset($this->data->/* redacted */) || !isset($this->data->/* redacted */)) { 
      if($this->logger !== null) 
       $this->logger->write("error", "Data object does not contain a valid administrator."); 

      return false; 
     } 

     $compare = // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
      // redacted 
     // redacted 

     $isValid = hash_equals($compare, $_SESSION[/* redacted */]); 

     if(!$isValid) { 
      if($this->logger !== null) 
       $this->logger->write("error", "Illegal session presented by {$_SERVER["REMOTE_ADDR"]}."); 

      return false; 
     } 

     return true; 
    } 

Snippet meiner log (nach dem Ausfüllen einmal Anmeldung)

2016-11-01 09:18:55 – [info] Session (359hk6v83pc3a82b9tlbn79ch5) moved to (6g05qcg7pocaht66ru5gdq8di6). 
2016-11-01 09:18:55 – [info] successful login from 127.0.0.1. 
2016-11-01 09:18:55 – [info] User ([email protected]) created in session (6g05qcg7pocaht66ru5gdq8di6). 
2016-11-01 09:19:08 – [info] Session (6g05qcg7pocaht66ru5gdq8di6) moved to (jo0etnds61ip2ices59hrg1jl6). 

Das Merkwürdige im letzten Snippet ist, dass es nach dem Verschieben der Sitzung auf eine neue ID nichts protokolliert. Ich würde erwarten (wie es der Fall ist, wenn ich den Zugriff auf Seiten versuchen, ohne Anmeldung) zumindest die folgenden in meinem Log: 2016-11-01 10:08:47 – [error] Session (jo0etnds61ip2ices59hrg1jl6) does not contain a valid administrator. - Seltsames Verhalten auf der Login-Seite ...


Fragen und Antworten

F: Haben Sie die Browserkonsole überprüft? Gibt es Warnungen bezüglich HTTPS? Vielleicht eine Warnung mit gemischten Inhalten oder etwas ähnliches? - CBroe
A: Keine wie auch immer. Die Anmeldeseite wird ohne Probleme geladen, sendet die Daten an den Server und der Server reagiert ordnungsgemäß. Es können keine Konsolenmeldungen zu HTTPS gefunden werden. Die Registerkarte Netzwerk zeigt auch keinen anderen Status als 200. Die Anmeldung wird einmal (über die POST-Anforderung) aufgerufen und die Seite wird anschließend aktualisiert. Ich kann den Sitzungscookie wie folgt verfolgen: 1 (initial load) -> keiner gesendet, 1 empfangen (071s21bdejg40supml9kamced5). 2 (POST zum Login) -> keine gesendet, 1 erhalten (813um7v1jjh3jsi57g5k8evm16) - Dies sollte kein Problem sein, oder? Da der Benutzer bei der neuen Sitzungs-ID angemeldet sein sollte. 3 (neu laden) -> 1 gesendet (071s21bdejg40supml9kamced5), 1 empfangen (k5aa0o4k24v2cfc41qbleq04h4) ...

Das eigentliche Problem wurde durch Überprüfung der gesendeten/empfangenen Cookies gefunden. Die Behebung dieses Problems hat nicht funktioniert.


Aktuelle Verständnis des Problems

Das Thema fand die Schritte beruhte ich nach CBroe Kommentar zu lesen war.

Es scheint, dass ich das falsche Session-Cookie vom Server zurückbekommen habe, und ich glaube, dass ich das der secureSessionStart-Funktion zuschreiben kann. Ich habe das Setzen von Cookies (zu Testzwecken) entfernt und ich bin richtig eingeloggt. Dies verhindert jedoch den gesamten Zweck der Verwendung sicherer Sitzungen mit Cookies, auf die das Skript nicht zugreifen kann. Wenn ich einfach session_start() verwende, ist alles in Ordnung und ich werde vom eigentlichen Back-End der Anwendung begrüßt. Immer wenn ich verwende, erscheint die Login-Seite immer wieder.


Abschließende Gedanken

Es ist wahrscheinlich ein fehlendes Semikolon irgendwo. Es ist immer ein fehlendes Semikolon ...

+1

Haben Sie die Browser-Konsole überprüft? Gibt es Warnungen bezüglich HTTPS? Vielleicht eine Warnung mit gemischten Inhalten oder etwas ähnliches? – CBroe

+0

Ich glaube, wir die Schuldigen gefunden, @Cbroe. Aktualisiert die Frage, wenn ich meine Idee umsetze, um dieses Problem zu beheben! – CytoDev

+0

@CBroe: Ich habe die Frage aktualisiert fanden die aktuelle Ausgabe zu reflektieren. – CytoDev

Antwort

1

Offenbar hat mein Server die sicheren Header nicht erhalten, und dies führte dazu, dass meine Login-Sitzung beim erneuten Laden verloren ging. Ich habe das derzeit behoben, indem ich überprüft habe, ob die Verbindung gesichert ist, bevor ich die Sitzung einstelle, vorausgesetzt, dies ist der Fall.


Haftungsausschluss

I DO NOT advise eine unsichere Verbindung mit Ihren Login-Anfragen zu behandeln! Wenn Sie das gleiche Problem ich haben, habe mit, sollten Sie prüfen, ob die Verbindung sicher ist den ganzen Weg Trog, bevor es in Ihrer Session-Cookie zu drehen!


Die aktuelle fix

Zwei kleine Ergänzungen der secureSessionStart Methode, um den Domain-Namen und Sicherheit für die Session-Cookie hinzuzufügen vorgenommen wurden. Bitte immer sicherstellen, dass die Verbindung ist sicher. Dies sollte nur zu Testzwecken erfolgen!

/** 
* get's the secure status from _SERVER 
* Also check against HTTP_X_FORWARDED and HTTP_X_FORWARDED_SSL because 
* some servers are behind load balancers. 
*/ 
$secure = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] === "on") && ((!empty($_SERVER["HTTP_X_FORWARDED_PROTO"]) && $_SERVER["HTTP_X_FORWARDED_PROTO"] === "https") || (!empty($_SERVER["HTTP_X_FORWARDED_SSL"]) && $_SERVER["HTTP_X_FORWARDED_SSL"] === "on")); 

// also use _SERVER["SERVER_NAME"] to set the cookie to this domain only 
session_set_cookie_params(0, "/", $_SERVER["SERVER_NAME"], $secure, true); 

Die ideale fix

Die ideale Lösung ist, nur auf jeder Seite SSL zu verwenden, die es erfordert. Die aktuelle Domäne, mit der ich arbeite, hat diese Einstellung nicht, und ich repariere das, während ich dies tippe. Ich mache nicht einmal Witze. Holen Sie sich Ihre SSL vor dem Aufbau Ihres Login-Systems.

Verwandte Themen