2014-03-04 4 views
10

aus dem Kochbuch Symfony 2: Understanding serialize and how a User is Saved in the Session:Warum lädt Symfony den Benutzer bei jeder Anforderung von der Datenbank neu?

Sobald der Benutzer angemeldet ist, wird das gesamte Benutzerobjekt in die Sitzung serialisiert. Bei der nächsten Anforderung wird das Benutzerobjekt deserialisiert. Anschließend wird der Wert der ID-Eigenschaft verwendet, um erneut nach einem neuen Benutzerobjekt aus der Datenbank abzufragen.

und

... in der Praxis bedeutet dies, dass das Benutzerobjekt aus der Datenbank auf jeder Anfrage mit der ID aus dem serialisierten Objekt neu geladen wird.

Warum muss Symfony das Benutzerobjekt bei jeder Anforderung aus der Datenbank holen?

Unter welchen Umständen würde das serialisierte Benutzerobjekt, das in den Sitzungsdaten gespeichert ist, nicht mit dem Benutzerobjekt übereinstimmen, das aus der Datenbank abgerufen wurde? Sicherlich weiß Symfony, wann sich das Benutzerobjekt ändert, und kann einfach die Sitzungsdaten aktualisieren, wenn dies geschieht.

Ich kann mir vorstellen, dass es einen guten Grund dafür gibt, da es unnötig wäre, die Datenbank bei jeder Anfrage unnötig abzufragen.

+1

Ich würde hinzufügen, wenn der Benutzer bei jeder Verbindung abgerufen wird, und es gibt einen guten Grund dafür, warum ist es in Sitzung serialisiert? – haltabush

+2

@haltabush Ich habe eine Erklärung dazu zu meiner Antwort hinzugefügt. – IMSoP

+0

Auf ihrer Dokumentationsseite vermerkt "Dies stellt sicher, dass alle Daten des Benutzers frisch sind." –

Antwort

12

Haftungsausschluss: Ich kenne Symfony nicht speziell, daher wird dies aus allgemeinen PHP-Kenntnissen und ein paar Annahmen geschrieben.

PHP-Sitzungen sind im Allgemeinen nicht von außen manipulierbar - sie sind nur ein serialisierter Datenblock in einer Datei oder einem Speicher. Die einzige Möglichkeit, eine zu ändern, besteht darin, sie zu deserialisieren, eine Änderung vorzunehmen und das Ganze zu reserialisieren - was normalerweise nur geschieht, wenn Sie in dieser Sitzung sind.

Wenn also die Benutzerdetails außerhalb der angemeldeten Sitzung geändert werden, bleibt das serialisierte Blob veraltet. Dies wäre beispielsweise dann ein besonderes Problem, wenn ein Administrator die Zugriffsrechte des Benutzers widerruft.

Ein Cache wie Memcached kann Details zu jedem Benutzer speichern und beim Editieren explizit geleert/geändert werden. Dies würde jedoch als Teil des Datenbankabrufs betrachtet werden (die Memcached-Ebene fungiert als schnellerer Zugriff auf die Datenbankdaten). nicht die Sitzungsbehandlung.


Als haltabush in einem Kommentar gefragt: wenn der Benutzer bei jeder Anfrage abgerufen wird, warum es serialisiert überhaupt?

Die Antwort ist, dass genügend Informationen in der Sitzung gespeichert werden müssen, um zu identifizieren, welcher Benutzer angemeldet ist, und ihre vollständigen Details beim nächsten Laden der Seite abrufen. Dies könnte so einfach sein wie das Speichern der Benutzer-ID, aber unter Verwendung der Serializable Schnittstelle kann Symfony es einer bestimmten Implementierung überlassen, zu entscheiden, welche Felder in der Sitzung gespeichert werden sollen und welche wieder abgerufen werden sollten, wenn dies der Fall ist unserialisiert.

Es bleibt auch die Option für eine Implementierung offen, alle Details des Benutzers in der Sitzung zu speichern, und auf einer entspannteren Basis, z. nach einer festgelegten Zeit oder Anzahl von Anfragen, wie unter this related question diskutiert.

+0

Das beantwortet meine Frage perfekt, danke. Ich hatte nicht daran gedacht, dass widerrufene Privilegien möglicherweise nicht sofort wirksam werden würden, wenn Symfony sich nur auf die Sitzungsdaten verlassen würde. –

3

Unter welchen Umständen würde das serialisierte Benutzerobjekt, das in den Sitzungsdaten gespeichert ist, nicht mit dem Benutzerobjekt übereinstimmen, das aus der Datenbank abgerufen wurde?

Zum Beispiel, wenn der Administrator ändert, welche Rechte/Berechtigungen ein Benutzer hat - das ist in der Regel etwas, das Sie sofort, und das nicht nur wirksam sein soll, wenn sich der Benutzer abmeldet und dann wieder in der nächsten Zeit.

Sicherlich Symfony weiß, wenn das Benutzerobjekt ändert, und können einfach die Sitzungsdaten aktualisieren, wenn dies auftritt?

Nicht, wenn diese Änderung keine Verbindung zur Sitzung des Benutzers hat, wie dies im oben genannten Szenario der Fall ist.

+0

Sie antworten auch Nägel es; Ich hatte nicht daran gedacht, dass das Entziehen der Berechtigungen eines Benutzers sich nicht auf die Sitzungsdaten auswirkt. Da ich nur eine Antwort akzeptieren kann, muss ich die annehmen, die zuerst beantwortet wurde. –

+0

@RichardKeller Eigentlich stimmt das nicht ganz. In der Standardimplementierung aktualisiert Symfony nicht alle Rollen und Berechtigungen für jede Anforderung. Es überprüft den Benutzernamen, das Salt und das Kennwort, obwohl dies im Benutzerlandcode durch Implementierung der Schnittstellen AdvancedUserInterface oder EquatableInterface überschrieben werden kann. Siehe AbstractToken :: hasUserChanged() (https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php#L244) – liquorvicar

Verwandte Themen