Sessions

HTTP ist ein zustandsloses Protokoll, jedoch muss fast jede Anwendung den Zustand zwischen Anfragen aufrechterhalten, beispielsweise den Inhalt eines Warenkorbs. Genau dafür dienen Sessions oder Sitzungen. Wir zeigen Ihnen,

  • wie man Sessions verwendet
  • wie man Namenskonflikte vermeidet
  • wie man die Ablaufzeit einstellt

Bei der Verwendung von Sessions erhält jeder Benutzer eine eindeutige Kennung, die sogenannte Session-ID, die in einem Cookie übermittelt wird. Diese dient als Schlüssel zu den Session-Daten. Im Gegensatz zu Cookies, die auf der Browserseite gespeichert werden, werden die Daten in der Session auf der Serverseite gespeichert.

Die Session wird in der Konfiguration eingestellt, wichtig ist insbesondere die Wahl der Ablaufzeit.

Die Verwaltung der Session übernimmt das Objekt Nette\Http\Session, auf das Sie zugreifen können, indem Sie es sich mittels Dependency Injection übergeben lassen. In Presentern reicht es aus, $session = $this->getSession() aufzurufen.

Installation und Anforderungen

Session starten

Nette startet die Session standardmäßig automatisch in dem Moment, in dem wir beginnen, Daten daraus zu lesen oder hineinzuschreiben. Manuell wird die Session mit $session->start() gestartet.

PHP sendet beim Starten der Session HTTP-Header, die das Caching beeinflussen, siehe session_cache_limiter, und gegebenenfalls auch ein Cookie mit der Session-ID. Daher ist es notwendig, die Session immer zu starten, bevor irgendeine Ausgabe an den Browser gesendet wird, andernfalls wird eine Ausnahme ausgelöst. Wenn Sie also wissen, dass während des Renderns der Seite die Session verwendet wird, starten Sie sie manuell vorher, zum Beispiel im Presenter.

Im Entwicklermodus startet Tracy die Session, da sie diese zur Anzeige von Balken mit Weiterleitungen und AJAX-Anfragen in der Tracy Bar verwendet.

Abschnitte

In reinem PHP wird der Datenspeicher der Session als Array realisiert, das über die globale Variable $_SESSION zugänglich ist. Das Problem dabei ist, dass Anwendungen üblicherweise aus einer Reihe voneinander unabhängiger Teile bestehen, und wenn alle nur ein Array zur Verfügung haben, kommt es früher oder später zu Namenskollisionen.

Das Nette Framework löst dieses Problem, indem es den gesamten Raum in Abschnitte (Objekte Nette\Http\SessionSection) unterteilt. Jede Einheit verwendet dann ihren eigenen Abschnitt mit einem eindeutigen Namen, und es kann zu keiner Kollision mehr kommen.

Einen Abschnitt erhalten wir aus der Session:

$section = $session->getSection('eindeutigerName');

Im Presenter genügt es, getSession() mit einem Parameter zu verwenden:

// $this ist Presenter
$section = $this->getSession('eindeutigerName');

Die Existenz eines Abschnitts kann mit der Methode $session->hasSection('eindeutigerName') überprüft werden.

Mit dem Abschnitt selbst arbeitet man dann sehr einfach mithilfe der Methoden set(), get() und remove():

// Variable schreiben
$section->set('userName', 'franta');

// Variable lesen, gibt null zurück, wenn sie nicht existiert
echo $section->get('userName');

// Variable löschen
$section->remove('userName');

Um alle Variablen aus einem Abschnitt zu erhalten, kann eine foreach-Schleife verwendet werden:

foreach ($section as $key => $val) {
	echo "$key = $val";
}

Ablaufzeit einstellen

Für einzelne Abschnitte oder sogar einzelne Variablen kann eine Ablaufzeit eingestellt werden. So können wir die Anmeldung eines Benutzers nach 20 Minuten ablaufen lassen, aber den Inhalt des Warenkorbs weiterhin speichern.

// Abschnitt läuft nach 20 Minuten ab
$section->setExpiration('20 minutes');

Zur Einstellung der Ablaufzeit einzelner Variablen dient der dritte Parameter der Methode set():

// Variable 'flash' läuft bereits nach 30 Sekunden ab
$section->set('flash', $message, '30 seconds');

Vergessen Sie nicht, dass die Ablaufzeit der gesamten Session (siehe Session-Konfiguration) gleich oder länger sein muss als die bei einzelnen Abschnitten oder Variablen eingestellte Zeit.

Das Löschen einer zuvor eingestellten Ablaufzeit erreichen wir mit der Methode removeExpiration(). Das sofortige Löschen des gesamten Abschnitts stellt die Methode remove() sicher.

Ereignisse $onStart, $onBeforeWrite

Das Objekt Nette\Http\Session hat die Ereignisse $onStart und $onBeforeWrite, Sie können also Callbacks hinzufügen, die nach dem Start der Session oder vor ihrem Schreiben auf die Festplatte und dem anschließenden Beenden aufgerufen werden.

$session->onBeforeWrite[] = function () {
	// Wir schreiben Daten in die Session
	$this->section->set('basket', $this->basket);
};

Session-Verwaltung

Übersicht der Methoden der Klasse Nette\Http\Session zur Session-Verwaltung:

start(): void

Startet die Session.

isStarted(): bool

Ist die Session gestartet?

close(): void

Beendet die Session. Die Session wird automatisch am Ende des Skriptlaufs beendet.

destroy(): void

Beendet und löscht die Session.

exists(): bool

Enthält die HTTP-Anfrage ein Cookie mit einer Session-ID?

regenerateId(): void

Generiert eine neue zufällige Session-ID. Die Daten bleiben erhalten.

getId(): string

Gibt die Session-ID zurück.

Konfiguration

Die Session wird in der Konfiguration eingestellt. Wenn Sie eine Anwendung schreiben, die keinen DI-Container verwendet, dienen diese Methoden zur Konfiguration. Sie müssen aufgerufen werden, bevor die Session gestartet wird.

setName (string $name): static

Legt den Namen des Cookies fest, in dem die Session-ID übertragen wird. Der Standardname ist PHPSESSID. Dies ist nützlich, wenn Sie mehrere unterschiedliche Anwendungen innerhalb einer Website betreiben.

getName(): string

Gibt den Namen des Cookies zurück, in dem die Session-ID übertragen wird.

setOptions (array $options)static

Konfiguriert die Session. Es können alle PHP Session-Direktiven (im CamelCase-Format, z.B. statt session.save_path schreiben wir savePath) sowie readAndClose eingestellt werden.

setExpiration (?string $time)static

Legt die Inaktivitätsdauer fest, nach der die Session abläuft.

setCookieParameters (string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null)static

Einstellung der Parameter für das Cookie. Die Standardwerte der Parameter können Sie in der Konfiguration ändern.

setSavePath (string $path)static

Legt das Verzeichnis fest, in dem die Session-Dateien gespeichert werden.

setHandler (\SessionHandlerInterface $handler)static

Einstellung eines eigenen Handlers, siehe PHP-Dokumentation.

Sicherheit geht vor

Der Server geht davon aus, dass er immer mit demselben Benutzer kommuniziert, solange die Anfragen von derselben Session-ID begleitet werden. Die Aufgabe der Sicherheitsmechanismen besteht darin, sicherzustellen, dass dies tatsächlich der Fall ist und es nicht möglich ist, die Kennung zu stehlen oder unterzuschieben.

Das Nette Framework konfiguriert daher die PHP-Direktiven korrekt, um die Session-ID nur im Cookie zu übertragen, sie für JavaScript unzugänglich zu machen und eventuelle Kennungen in der URL zu ignorieren. Darüber hinaus generiert es in kritischen Momenten, wie z. B. bei der Benutzeranmeldung, eine neue Session-ID.

Zur Konfiguration von PHP wird die Funktion ini_set verwendet, die leider von einigen Hostern verboten wird. Wenn dies auch bei Ihrem Hoster der Fall ist, versuchen Sie, mit ihm zu vereinbaren, dass er Ihnen die Funktion erlaubt oder zumindest den Server konfiguriert.

Version: 4.0