Hi Sven, Hi Thomas!
Der Trick ist, dass man, noch bevor eine Session gestartet wird, erstmal die Anmeldedaten auswertet. Dann guckt man nach, ob diese Anmeldedaten schon eine zugeordnete Session besitzen, und setzt in diesem Fall die Session-ID auf die gespeicherte ID.
Und wie macht man das ohne die Session zu starten? Wo genau guckst Du was nach? Ich wäre jetzt auf die Idee gekommen, genau wie Du erstmal die Anmeldung zu überprüfen, aber das lasse ich vom Apachen erledigen, so habe ich einen rundum-Schutz und bin unabhängiger von PHP. Also wenn das Script dann also geladen wird kann ich davon ausgehen dass die Zugangsdaten gültig sind. Dann hätte ich folgende Idee:
Ich weise einfach den Usernamen als Session zu oder ist das blöd?
Einfach
session_id($_SERVER["REMOTE_USER]);
session_start();
Dann übernimmt der Session-Mechanismus den Rest, er legt entweder eine neue Session an oder greift auf die vorhandene zu, und ich habe schön meine sicheren HTTP-AUTH Daten die ich zur Wiedererkennung verwende. Das sollte doch gut funktionieren, oder? Dann müßte man nur Cookies etc alles abschaltenn. Wenn man dann für die Session-Files ein ganz eigenes Verzeichnis erstellt, hat man hierüber sogar ohne Session zu starten Zugriff auf die Daten, man kann schon an den Dateinamen sehen welche User eingeloggt sind, etc, man könnte sich sogar eben den Quellcode ansehen wie das Parsen der Session-Datei aussieht, ich habe auch mal kurz gesucht, ist aber ein wenig Komplex das ganze ;-)
Das ganze läuft simpel so ab (zugegeben: PHP 4.0.x):
if (Alte Session soll übernommen werden)
{
session_id($alte_sessionid);
wo hast Du die alte SessionID her?
}
else
{
session_id($PHPSESSID)
}
kann man den Else-Teil nicht weglassen?
session_start();
Nun gesetzt den fall, man will dem besucher jedesmal die selbe Sessionnummer geben, dann könnte er einen angefangenen Vorgang beim nächsten Mal fortsetzen. Könnte ja sein, dass er das nun vom PC seiner Schwester aus tun muss, die aber aus Prinzip Angst vor Cookies hat (OK, dann sollte er sich viellicht ne andere Schwester suchen *gg*), dann könnte er bei gleichem Format von interner Serialisierung und serialize() die Session auch mit auth übernehmen. Das Dagtenmodell wäre an dieser Stelle nicht gebrochen und man würde von einer "sauberen Lösung" sprechen können.
Die Fraeg ist ob der Session-Mechanismus für solche Sachen gedacht ist udn gedacht seoin sollte! Wir wollen ja keine eierlegende WollMilchSau die irgendwie alles ein bisschen aber nichts richtig kann. Für normale Session-Anwendungen ist der Mechanismus so gut wie er ist, wer es anders braucht schreibt sich seinen Handler oder einen eigenen Mechanismus. Und nicht dass Du denkst ich wolle hier Ärger machen oder sowas, ich hatte mich jetzt nur wirklich eingehender mit der Problematik befaßt, und je mehr ich das tue desto sicherer bin ich mir das Du nichtmal einen anderen Handler brauchen solltest!
Ich plane nämlöich ebenfalls eine Kombination aus HTTP Auth und Sessions, um ein Objekt mit allen möglichen Daten in der Session zu haben, so dass ich nur einmal pro Besuch alle möglichen Konfig-Files und DB-Einträge wie Rechte, indiv. Menüleiste... laden muß. Wenn ich auf die Daten zugreifen will mach eich das schlicht und einfach mit $_SESSION, ich wüßte nicht wo da ein Problem bestehen könnte!
Gesucht wird also, wenn ich Fabian hier mal unterstützen darf, eine Methode, mit der man die Sicherung und Wiederherstellung der Daten bei Session mit dem original session_start() in das Format von serialize()/unserialize() bringen kann.
Obwohl ich den Satz jetzt nicht zu 100% verstehe, probiere ich trotzdem: Das Format in der Session-Datei _entspricht_ doch serialize(), oder? Der Unterschied besteht nur darin das Du mit Serialize() immer nur eine Variable behandelst, in der Session stehen nunmal mehrere. In der Session steht das meines Wissens so:
bei integer:
<var_name>|i:<INT-Wert>;
bei string:
<var_name>|s:<anzahl zeichen>:"<STRING-Wert>";
bei array:
<var_name>|a:<anzahl elemente>:{<ELEMENTE mit i,s,o oder a>}
bei object:
<var_name>|o:<anzahl elemente>:{<ELEMENTE mit i,s,o oder a>}
Alles was hinter "<var_name>|" steht entspicht serialize(). Ich habe halt kurz einen Parser gebaut, der alle Buchstaben bis | in einen String schreibt, diesen als Variablennamen verwendet, alles dahinter bis zu einer sich schließender Klammer und wenn dann keine mehr offen ist komplett durch serialize() schickt und das Ergebnis dem zuvor ermittelten Namen zuweist, die andere Variante(für i und s) funktioniert genau so nur das hier statt nach einerm } nach einem ; gesucht wird. Wenn man noch ein bisschen dran feilt kommt am Ende der Session-Array raus ohne die Session gestartet zu haben. Das Problem an meinem Ansatz ist nur, dass wenn irgendeins von den magischen Zeichen in dem serialisierten String vorkommt, dass dann vermutlich einiges daneben geht. Daher müßte man sich einen richtigen Parser schreiben, der auf unserialize() verzichtet und das ganze "manuell" parst. Dürfte auch nicht so wild sein, wie gesagt müßte das ja auch irgendwo im PHP-Quelltext als Vorlage in C stehen, nur sehe ich halt keine Notwendigkeit das zu tun.
Es wird wohl nichts anderes übrig bleiben, als session_set_save_handler() zu verwenden und für read und write die Funktionen einzusetzen, die man auch für "Auth-Sessions" benutzt. Da kann ich aber leider auch nicht weiterhelfen.
Ich frage mich immer noch warum denn wenn schon der Session-Mechanismus benutzt wird nicht einfach auf $_SESSION zugegriffen wird? Vermutlich bin ich etwas schwer von Begriff, aber ich verstehe es nunmal nicht. Die obige Struktur läßt sich mit einem recht kleinen Script bestimmt gut parsen, ich hatte das in Ansätzen probiert, das geht sicher genau so gut wie PHP das selbst macht.
Viele Grüße
Andreas