In unserer (n) Intranet-Anwendung (en) verwenden wir SSO (Single Sign-On) Login, während die Sitzungen sowohl auf Client- als auch auf Authentifizierungs-Anwendungen in memcached gespeichert sind.
Die Sitzungen sind so eingestellt, dass sie 12 Stunden leben, bevor der Garbage Collector sie als Entfernung ansieht. Beide Anwendungen werden mit ZF2 geschrieben.
Leider ist das Problem, dass der Browser nach einer bestimmten Zeit (ich habe nicht den genauen Wert) die Sitzung verliert, die die Umleitung zum Ursprung der Authentifizierung verursacht, wo die Sitzung noch am Leben ist und der Benutzer zurückgeleitet wird Client und die Browsersitzung wird aktualisiert. Dies ist keine große Sache, wenn der Benutzer keine ungespeicherte Arbeit hat, da diese zwei Umleitungen innerhalb von 1 Sekunde stattfinden und der Benutzer sie möglicherweise nicht bemerkt.
Aber es ist wirklich eine große Sache, wenn der Benutzer nicht gespeicherte Arbeit hat und sogar ein Versuch, es zu speichern, führt zu Weiterleitungen und die Arbeit ist weg.
Hier ist die Konfiguration der Sitzung in Bootstrap.php
:
Der Authentifizierungsdienst ist als
definiert %Vor% Dann irgendwo innerhalb der Anwendung muss ein Session-Wert abgerufen oder gesetzt werden Ich verwende einfach ein \Zend\Session\Container
wie folgt:
Das SSO wird für die aktive Sitzung bei jeder Aktion mit dem Token aus der Sitzung angefordert, die PHPSESSID vom Auth-Ursprung enthält. Es ist ziemlich kompliziert hier in dieser Frage zu beschreiben.
Zusätzlich speichert ein Authentifizierungsdienst eine Benutzeridentität (mit Rollen für ACL) auch in der Memcached-Sitzung - unter Verwendung der gleichen Einstellungen. Offensichtlich ist dies jetzt der Ort, der Verwirrung stiftet. Anscheinend wird der Sitzungsspeicher des Authentifizierungsdienstes vorzeitig beendet, was dazu führt, dass die ACL keine Benutzeridentität abruft, um in die Abmeldefolge von SSO zu gelangen (da sich der Benutzer jedoch nicht wirklich abgemeldet hat, leitet SSO den Benutzer wie oben beschrieben zurück).
Ich bin mir nicht sicher, wie viel Code ich (und kann ich) hier teilen soll, vielleicht wirst du mich sofort zur Lösung bringen oder mir einfach ein paar Fragen stellen. Nach vielen Stunden Debugging bin ich ziemlich hilflos und versuche das Problem zu identifizieren.
Irgendwo, das ich gelesen habe, löscht memcached den Speicher, sobald die Sitzung cookie 1MB groß wird - ist das vielleicht der Fall? Für die Benutzeridentität speichern wir nur allgemeine Benutzerinformationen und ein Array von Rollen, ich denke, das könnte max. bis zu einigen kb Größe ...
EDIT 1: Um alle Vermutungen zu verwerfen und um Ihre Zeit zu sparen, hier ein paar Fakten (zu beachten):
PHPSESSID
zwischen dem Browser und dem Server zu transportieren, und der Wert ist der Schlüssel für den Speicherblock in memcached, wo die Daten gespeichert werden Ich werde einige die
s in PHP und return
s in JS-Teile implementieren, um den Moment zu erfassen, wenn die Sitzung als erledigt betrachtet wird, und weitere Browser-Cookies, Memcached-Daten usw. zu inspizieren. es sei denn, jemand kommt mit Erklärung und Lösung).
Dies ist die Funktion, die ich verwende, um ein Cookie für X Benutzer zu erstellen. Der Cookie lebt 3 Stunden, egal ob es Weiterleitungen gibt oder der Benutzer den Browser geschlossen hat. Es ist immernoch da. Rufen Sie diese Funktion einfach in Ihrer onBootstrap () - Methode aus der Module.php auf.
Während der Protokollierung verwende ich den ZF2 AuthenticationService und den Container, um die Benutzerdaten zu speichern und abzurufen.
Ich empfehle Ihnen, dieses Modul zur einfacheren Fehlersuche zu installieren. Ссылка Ссылка
Wenn memcached
als session.save_handler
verwendet wird, wird die Garbage Collection der Sitzung nicht durchgeführt.
Da Memcached mit einem TTL-Wert (Time to Live) arbeitet, ist eine Speicherbereinigung nicht erforderlich. Ein Eintrag, der nicht lange genug gelebt hat, um das TTL-Alter zu erreichen, wird als "frisch" betrachtet und verwendet. Danach wird es als "veraltet" angesehen und nicht mehr verwendet. Schließlich wird Memcached den Speicher freigeben, der von dem Eintrag verwendet wird, aber das hat nichts mit Session-Garbage Collection von PHP zu tun.
Tatsächlich ist die einzige session.gc_
Einstellung, die in diesem Fall tatsächlich verwendet wird, session.gc_maxlifetime
, die als TTL an Memcached übergeben wird.
Kurz gesagt: Garbage Collection ist in Ihrem Fall kein Problem.
Wenn Sie Memcached als Speicher für Ihre Sitzungen verwenden, werden alle vom Betriebssystem bereitgestellten Cronjobs, die Sitzungsordner auf der Festplatte manuell bereinigen (wie Ubuntu), keinen Effekt haben . Memcached ist Speicher, nicht Plattenspeicher.
Kurz gesagt: Cronjobs wie dieses sind in Ihrem Fall kein Problem.
Sie geben an, dass sich der SSO-Server / die SSO-Autorität auf demselben Computer wie der SSO-Client (die Anwendung selbst) befindet, dieselbe Webserver / PHP-Konfiguration verwendet und dieselbe Instanz von Memcached verwendet.
Dies lässt mich glauben, dass wir suchen müssen, wie die Sitzungsverwaltung in der Anwendung ausgeführt wird, da dies der einzige Unterschied zwischen der SSO-Autorität und dem Client ist. Mit anderen Worten: Wir müssen in Zend \ Session eintauchen.
Haftungsausschluss: Ich habe professionell an mehreren Zend Framework 1 Anwendungen gearbeitet, aber nicht an irgendwelchen Zend Framework 2 Anwendungen. Also fliege ich hier blind:)
Eine Sache, die ich in Ihrer Konfiguration bemerke, ist, dass Sie cookie_lifetime
auf 0
gesetzt haben. Dies bedeutet eigentlich "bis der Browser schließt". Das macht keinen Sinn, wenn remember_me_seconds
auf 12 Stunden eingestellt ist, weil viele Leute ihren Browser vor dieser Zeit geschlossen haben.
Ich schlage vor, dass Sie cookie_lifetime
auch auf 12 Stunden setzen.
Beachten Sie auch, dass remember_me_seconds
nur verwendet wird, wenn die Remember Me-Funktion tatsächlich verwendet wird. Mit anderen Worten: wenn Zend\Session\SessionManager::rememberMe()
aufgerufen wird.
Wenn Sie sich ansehen, wie Sie Memcached als Sitzungsspeicher implementiert haben und was ich zu diesem Thema finden kann, würde ich sagen, dass Sie etwas anderes gemacht haben als das, was "der bevorzugte Weg" zu sein scheint.
> Die meisten Ressourcen zu diesem Thema empfehlen die Verwendung von Zend\Session\SaveHandler\Cache
( doc , api ) als Save-Handler, Das gibt Ihnen die Möglichkeit, Zend\Cache\Storage\Adapter\Memcached
zu verwenden ( doc , api ). Dies gibt Ihnen viel mehr Kontrolle über das, was vor sich geht, weil es nicht auf den begrenzten memcached
session-save-handler angewiesen ist.
Ich schlage vor, dass Sie diese Implementierung versuchen. Wenn es Ihr Problem nicht sofort beheben kann, gibt es mindestens viel mehr Ressourcen zu dem Thema zu finden. Ihre Chancen, eine Lösung zu finden, werden besser IMHO sein.
Diese Antwort behandelt möglicherweise nicht sofort die Ursache Ihres Memcache-Problems, aber aufgrund der Unzuverlässigkeit von Memcache würde ich vorschlagen, eine Sicherungskopie Ihrer Memcached-Daten in einem dauerhaften Speicher zu erstellen. Das Speichern Ihrer Daten hilft Ihnen, die Leistung Ihrer Anwendung zu verbessern, ist jedoch nicht ausfallsicher.
Vielleicht können Sie einen Fallback-Speicher (persistent) in Ihrer AuthenticationService
-Instanz erstellen. Dann versuchen Sie zuerst, Ihre Authentifizierungsdaten aus Ihrem Memcache zu holen, und wenn nichts gefunden wird, prüfen Sie, ob in Ihrem persistenten Speicher etwas verfügbar ist.
Dies wird zumindest alle Probleme mit unerwarteten Memcacheverlustproblemen lösen.
Tags und Links php session authentication memcached zend-framework2