getJSON und session_regenerate_id ()

8

Ich führe eine Standard-getJSON-Abfrage von einer Seite aus, die sitzungsgeschützt ist:

%Vor%

In meinem Session-Konstruktor habe ich folgendes eingestellt:

%Vor%

Wenn ich SESSION_REGENERATE_ID auf true setze, sendet mein getJSON ein Token, erhält aber ein anderes Token, wodurch die Anfrage fehlschlägt. Also im Moment habe ich mit SESSION_REGENERATE_ID auf false gesetzt.

Gibt es eine Möglichkeit, getJSON unter solchen Bedingungen arbeiten zu lassen?

BEARBEITEN: Alle Dateien sind unter der gleichen Domäne.

Wir haben index.php, wo die js enthalten ist, wir haben queries.php, das ist die php-Datei, die von den ajax-Anfragen aufgerufen wird, wir haben s_session.php, die den oben geschriebenen Konstruktor enthält.

Dateien index.html und queries.php sind beide am Anfang auf diese Weise geschützt:

%Vor%

Die PHPSESSID befindet sich im Header der Ajax-Anfrage unter set-cookie. Die in der Antwort zurückgegebene PHPSESSID ist anders als erwartet von session_regenerate_id.

Wenn SESSION_REGENERATE_ID auf FALSE gesetzt ist, laufen die Anfragen ohne Probleme. Wenn es auf TRUE gesetzt ist, bekomme ich die Fehlermeldung "Login failed".

Hier ist das isLoggedIn ():

%Vor%

EDIT 2: Hier ist der vollständige ASSession-Code:

%Vor%

EDIT 3: Hier sind die Anfrage Header und Antwort-Cookie:

Ich habe bemerkt, dass der allererste getJSON, der während der onload ausgeführt wird, erfolgreich ist. Alle anderen nach und ausgelöst durch Benutzer sind erfolglos

    
Vincent Teyssier 25.01.2016, 12:55
quelle

1 Antwort

2

Dies wird meistens durch eine Race-Bedingung verursacht, aber ein Browser-Bug ist auch möglich.

Ich würde das Browser-Fehlerszenario ausschließen, aber es gibt einen Konflikt in den bereitgestellten Informationen, genauer gesagt in Dieser Kommentar :

  

Es sind mehrere Aufrufe, die nacheinander für Benutzeraktionen durchgeführt werden, niemals gleichzeitig.

Wenn die Anfragen nie gleichzeitig ausgeführt werden , könnte das nur bedeuten, dass Ihr Browser nicht ordnungsgemäß funktioniert und eine der folgenden Situationen eintritt:

  • Verwerfen des Headers Set-Cookie , den er in der Antwort erhält (wenn diese Logik vom Flag HttpOnly abhängt, würde dies erklären, warum das Web noch funktioniert: D) ​​
  • Das onLoad -Ereignis wurde tatsächlich beim Laden der Seite ausgeführt (ich weiß, dass das keinen Sinn ergibt, aber alles ist möglich, wenn es sich um einen Browser-Fehler handelt)

Natürlich ist es sehr unwahrscheinlich, dass dies passiert, also bin ich geneigt zu sagen, dass Sie tatsächlich mehrere AJAX-Anfragen gleichzeitig bearbeiten, in welchem ​​Fall die Race Condition ein plausibles Szenario ist:

  1. Die erste Anfrage beginnt (mit Ihrer anfänglichen PHPSESSID)
  2. Die zweite Anfrage beginnt (wiederum mit der gleichen PHPSESSID)
  3. Die erste Anfrage wird bearbeitet und erhält eine Antwort mit einer neuen PHPSESSID
  4. Die zweite Anfrage wurde bis jetzt blockiert (der Session-Handler verwendet Sperren, um zu verhindern, dass mehrere Prozesse dieselben Daten gleichzeitig bearbeiten) und gerade jetzt beginnt, mit der anfänglichen PHPSESSID , was an dieser Stelle ungültig ist, weshalb es eine Abmeldung auslöst.

Ich würde mir persönlich anschauen, was von diesem onLoad -Ereignis ausgelöst wird - es ist einfach, einfach alle Initialisierungslogik dorthin zu legen und zu vergessen, dass dies mehrere asynchrone Anfragen enthalten kann.

In jedem Fall ist der wahre logische Fehler Ihrerseits dieser Code:

%Vor%

Sie verwenden denselben Wert für zwei verschiedene Bedingungen:

  1. Bestimmen, ob die Sitzungs-ID überhaupt neu erstellt werden soll
  2. % session_regenerate_id() mitteilen, wenn Daten, die mit der alten Sitzungs-ID verknüpft sind, sofort gelöscht werden sollen

Die Option not zerstört die Daten sofort, um genau diese Bedingungen mit asynchronen Anfragen zu lösen, weil sie praktisch unvermeidlich sind. Eine Race-Bedingung wird irgendwann passieren, unabhängig davon, wie sehr du versuchst, sie zu vermeiden - selbst wenn es keinen logischen Fehler gibt, können Netzwerkverzögerungen (zum Beispiel) sie trotzdem auslösen.
Das Beibehalten der Daten der alten Sitzung (vorübergehend natürlich) umgeht dieses Problem, indem einfach eine "verspätete" oder "nicht synchronisierte" Anfrage mit den zum Zeitpunkt des Starts verfügbaren Daten arbeiten kann.

Abgelaufene Sitzungen werden später vom Sitzungs-Garbage-Collector bereinigt. Das ist möglicherweise nicht ideal, aber so ziemlich die einzige Lösung für Speicher, bei denen Sie Daten löschen müssen (im Gegensatz zu Cache-Speichern wie Redis, mit denen Sie einen TTL-Wert festlegen können, anstatt manuell löschen zu müssen).

Persönlich bevorzuge ich es, die Session ID Regeneration speziell während AJAX Anfragen zu vermeiden ... wie Sie sehen, ist es eine Dose Würmer. :)

    
Narf 29.01.2016, 19:26
quelle

Tags und Links