Wofür braucht ein normaler Mensch Sessions?

|
|
HTTP leidet an akuter Amnesie und vergisst leider alles was weiter als ein Formular entfernt ist:
Wenn Sie ein Formular submitten, können Sie in der nächsten angezeigten Seite noch sagen, was der
Benutzer eingegeben hat, in der übernächsten jedoch nicht mehr. Das ist ziemlich unpraktisch,
etwa wenn Sie Assistenten anbieten, auf denen der Benutzer über mehrere Seiten Eingaben machen kann,
die erst am Ende in eine Datenbank geschrieben werden sollen oder wenn Sie möchten, dass
sich Ihre Benutzer einloggen, und dann auf jeder Seite überprüfen, ob der Benutzer authorisiert ist
(obwohl ich da ein angepasstes
HTTP-Auth beinahe
empfehlen würde).
Theoretisch könnten Sie alle Formulardaten immer in Hidden Inputs in jede Seite schreiben aber das
wäre umständlicher als Sessions und erfordert eine Anzahl Hidden Inputs pro Seite die genauso
groß ist wie die Anzahl der Inputfelder in Ihrem gesamten Projekt. Wenn Sie diese Lösung noch
so programmieren, dass Sie einfach weitere Formularfelder hinzufügen können, ohne die
anderen Seiten zu ändern (mit PHP geht das...) haben Sie sich defintiv zu viel Arbeit gemacht.
Wie funktionieren Sessions technisch?

|
|
Sie legen einmal eine Session an und erhalten eine ID zurück. PHP speichert dann alle Daten, die
unter dieser ID anfallen, zentral und abrufbereit auf dem Server. Der Browser behält sich (nur)
seine Session-ID in der Regel in einem Cookie. Ein Problem ist, wenn diese Cookies abgeschaltet sind, würde
die Session-ID auf jeder Seite verloren gehen, Sessions wären also vollkommen wirkungslos.
Deshalb gibt es die Möglichkeit, die Session ID, SID, auch in (ein einzelnes) Hidden Input
einzutragen oder als Parameter bei einem Link zu übergeben. Das heißt, Sie müssen jeden
Link, hinter dem Sie die Session noch gebrauchen wollen, so präparieren, dass er die Session ID
erhält, falls Sie Cookieablehnende Benutzer nicht vor den Kopf stoßen wollen.
Um Session Hijacking zu vermeiden (jemand anders loggt sich mit derselben SID wie ein angemeldeter
Benutzer ein), ist die Session ID eine Zufallszahl. Und um Angreifern ihr Handwerk zu erschweren
verfällt diese Session ID nach einer angegebenen Laufzeit, außerdem sind Benutzer gehalten, sich
auszuloggen (wobei die Session durch den Programmierer als ungültig erklärt wird).
Konfiguration von PHP: session.auto_start
Wie auch beim
Übernehmen von Formulardaten
gibt es bei den Sessions einen Trick, wie Sie es sich einfach machen können: In der php.ini
(unter Linux: /etc/php.ini, unter Windows:\windows\system32\php.ini) schalten Sie dazu
session.auto_start auf 1 und starten Sie Ihren Apache mit apachectl
reload neu. Ob dies auf Ihrem Webserver so gesetzt ist, können
Sie praktisch nur über die phpinfo()-Funktion kontrollieren, entweder schreiben Sie sich selbst kurz ein
<?php phpinfo(); ?> oder Sie verwenden das Beispiel in
Formulardaten übernehmen.
Ist session.auto_start nämlich 1, können Sie Sessions einfach verwenden, indem Sie das
assoziative Array $_SESSION
verwenden.
<!-- Bitte in die Datei test.php -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test2.php?<?=SID?>">next</a>
<!-- Bitte in die Datei test2.php -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test.php?<?=SID?>">next</a>
Beachten Sie, dass die Konstante SID in beiden Dateien im Link angegeben ist.
So funktioniert das Beispiel auch mit ausgeschalteten Cookies und zeigt dort dann
bei einem Seitenwechsel etwas in der Form test2.php?PHPSESSID=9970ac048cb8b015b5969f1a75e1c4fa
in der Adresszeile (und im Link).
Die Konstante SID
Die Session-ID können Sie an Links durch die Konstante SID anhängen. Ihr wird nicht, wie bei
Variablen, ein Dollarzeichen vorangestellt.
<a href="test.php?<?=SID?>">next</a>
Diese "Konstante" enthält den Namen, wie Session-IDs genannt werden (Standard:PHPSESSID), ein
Gleichzeichen und die ID. Sie sollten also an ihren Link vor der SID-Konstante ein ? oder
ein & anschließen, je nachdem, ob PHPSESSID der erste oder ein folgender Parameter ist
(Man verwendet zum Abgrenzen des Dateinamens vom ersten Parameter ein ? und zwischen den
Parametern ein &. Sollten Sie dieses Fragezeichen unterlassen, bekommt der Besucher wohl etwas wie
eine File-Not-Found-Fehlermeldung).
<a href="test.php?action=next&<?=SID?>">next</a>
SID in Formularen: session_id
Haben Sie ein Formular und möchten nicht, dass durch Drücken des Absenden-Buttons die Session
verloren geht, sollten Sie ein verstecktes Eingabefeld mit Namen PHPSESSID einbauen und mit der
ID der aktuellen Session belegen. Die Konstante SID ist in dem Fall wertlos, da sie nicht nur
die Session-ID speichert, sondern zusätzlich PHPSESSID= vornedran. Interessanter ist in dem Fall
wohl die Funktion session_id():
<form method="post" action="test2.php">
<input type="hidden" name="PHPSESSID" value="<?=session_id()?>">
<input type="submit">
</form>
PHPSESSID wird in dem Fall automatisch ausgewertet.
Die Variable _SESSION
_SESSION ist ein globaler
assoziativer Array, die Sie als solche nicht gesondert in Ihrer Funktion zu deklarieren
brauchen (keine Angabe von
global).
Eine Variable speichern Sie in der Session durch Angabe von $_SESSION['variablenname'] =
wert;, auslesen tun Sie sie logischerweise mit $auslesewert=$_SESSION['variablenname'].
Sitzungen beenden/verlassen
Beim ausloggen eines Benutzers sollten Sie PHP die Variablen in dieser Sitzung löschen lassen, damit
niemand anders, mit spionierter oder erratener Session-ID, die Session im eingeloggten Zustand kapern kann.
Dazu kann ein session_unset() nicht schaden. Der Dokumentation nach solle man bei Verwendung von $_SESSION
eher $_SESSION=array(); benutzen, das kann ich aber nicht nachvollziehen, weil session_unset() zumindest
in meinem System die gleiche Wirkung zu haben scheint. Allerdings verbietet auch niemand die
doppelt-gesichert-hält-besser-Taktik.
session_unset();
$_SESSION=array();
Sitzungen teilweise beenden
Sie können wie gewohnt mit
unset nur ausgewählte Sitzungsvariablen ungültig machen:
unset ($_SESSION["nameDerZuZerstoerendenVariable"]);
Schönen Gruß vom Programmierer: unset ($_SESSION) sollen Sie möglichst vermeiden :-)
(siehe Sitzungen beenden)
Sitzungen starten

|
|
Sitzungen starten und beenden sind, zumindest in PHP, zwei grundverschiedene Dinge:
Dieselbe Sitzung kann (und muss meistens) häufiger als einmal gestartet, darf und kann allerdings
nur einmal beendet werden. Ist
session.auto_start in der php.ini
aktiviert, wird sie bei Bedarf und so oft als nötig gestartet, beendet wird sie typischerweise
nur beim Ausloggen, durch den Programmierer immer extra anzugeben, durch
session_unset bzw. $_SESSION=array();. Gestartet im Sinne von session_start()
muss die Session immer werden, wenn Sie innerhalb der PHP-Datei verwendet werden soll, also in der
Regel in allen PHP-Dateien des Bereichs, in dem Sessions verwendet werden.
session_start() ist also eher eine Anmeldung zur Benutzung von Sessions. Existiert noch keine
Session-ID, wird diese allerdings beim ersten Session-Start angelegt.
Wie bei
header-Funktionen muss session_start() vor
jeder Ausgabe (wie echo oder auch nur einem Leerzeichen oder Zeilenvorschub im HTML-Quelltext)
erfolgen. Wie erwähnt wird es
nur benötigt, wenn
session.auto_start=0 ist
.
Das erste Beispiel für Systeme ohne Session-Auto_start:
<?php session_start(); ?>
<!-- Bitte in die Datei test.php -->
<!-- Keine Kommentare, Leerzeilen oder Leerzeichen - irgendwas - vor dem PHP-Block mit session_start. -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test2.php?<?=SID?>">next</a>
<?php session_start(); ?><!-- Bitte diese Zeile schon (incl. session_start()) in die Datei test2.php -->
<!-- Keine Kommentare, Leerzeilen oder Leerzeichen - irgendwas - vor dem PHP-Block mit session_start. -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test.php?<?=SID?>">next</a>