Sebastian: session.use_trans_sid verhindert Zerstören der Session

Hallo,

in meinem Login-System biete ich dem Benutzer die Möglichkeit, sich auszuloggen.

Wenn aber session.use_trans_sid auf 1 steht, also die SID automatisch an links gehängt wird, funktioniert session_destroy() nicht mehr.

Was kann hierfür die Ursache sein?

MfG
Sebastian

  1. Moin!

    Wenn aber session.use_trans_sid auf 1 steht, also die SID automatisch an links gehängt wird, funktioniert session_destroy() nicht mehr.

    Was kann hierfür die Ursache sein?

    Vermutlich kennst du die Funktion von session_destroy() nicht genau, bzw. erwartest Dinge, die diese Funktion nicht tut.

    Deshalb: Definiere "funktioniert nicht".

    - Sven Rautenberg

    --
    "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
    (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
    1. Deshalb: Definiere "funktioniert nicht".

      ich erwarte von der funktion, daß sie die korrespondierende sessiondatei im php-verzeichnis löscht und somit die daten vernichtet. damit ist die aktuelle SID erledigt. außerdem führe ich an dieser stelle noch ein unset auf $_SESSION aus, um auch im speicher aufzuräumen.

      1. hi,

        ich erwarte von der funktion, daß sie die korrespondierende sessiondatei im php-verzeichnis löscht und somit die daten vernichtet.

        eben das passiert aber nicht.
        php löscht die session_dateien_ zu irgendeinem späteren zeitpunkt über den garbage collector, der zufällig ausgelöst wird.

        gruss,
        wahsaga

        1. aber da ich mit $_SESSION=array(); und session_unset(); die daten vernichte, müsste trotzdem die session als beendet angesehen werden.

          aber vor allem, warum beeinflußt session.use_trans_sid die arbeitsweise des garbage collectors? das macht doch keinen sinn...

          1. Hallo,

            aber da ich mit $_SESSION=array(); und session_unset(); die daten vernichte, müsste trotzdem die session als beendet angesehen werden.

            aber vor allem, warum beeinflußt session.use_trans_sid die arbeitsweise des garbage collectors? das macht doch keinen sinn...

            Ich bin der Meinung, dass ein session _destroy() sofort die zugehörige Sessiondatei (und die Sessionvariablen und die Sessionnummer) löscht. Der Garbage Collector läuft davon völlig unabhängig und prüft lediglich das LastTouch-Datum der Dateien.

            Darum muss er im Session-Verzeichnis auch browsen können (also Leserecht für Verzeichnis). Wenn man das wegnimmt, dann tut der gar nix mehr.

            Mit session_unset() werden nur die Sessionvariablen des Scriptes gelöscht, nicht aber die Sessionnummer, denn die steht ja in $_SERVER[$sessionname], wobei $sessionname den Standardnamen PHP_SESSID hat.

            Grüße

            Tom

            1. Hi, sollte natürlich $_COOKIE heißen

              Mit session_unset() werden nur die Sessionvariablen des Scriptes gelöscht, nicht aber die Sessionnummer, denn die steht ja in

              $_COOKIE[$sessionname],

              wobei $sessionname den Standardnamen PHP_SESSID hat.

              Grüße

              Tom

            2. hi,

              Ich bin der Meinung, dass ein session _destroy() sofort die zugehörige Sessiondatei (und die Sessionvariablen und die Sessionnummer) löscht. Der Garbage Collector läuft davon völlig unabhängig und prüft lediglich das LastTouch-Datum der Dateien.

              meines wissens erklärt session_destroy nur die gültigkeit der session für beendet; die zur session im session-directory abgelegten dateien werden jedoch separat "entsorgt".

              und hier kommt der garbage collector zum einsatz, der zufällig gestriggert wird, und dann dort obsolete dateien löscht.
              der zufallsgesteuerte aufruf wird deshalb eingesetzt, weil es schlicht zu viel performance kosten würde, nach jeder aktion eine bereinigung der session-dateien durchzuführen.

              die häufigkeit, in der der garbage collector aktiv wird, lässt sich über die konfigurationseinstellung session.gc_probability beeinflussen.

              gruss,
              wahsaga

          2. Moin!

            aber da ich mit $_SESSION=array(); und session_unset(); die daten vernichte, müsste trotzdem die session als beendet angesehen werden.

            Allerhöchstens wird die Session mit leeren Werten fortgesetzt.

            Sessions funktionieren unter PHP so:
            Es wird ein Request registriert. Dieser startet ein Skript. Das Skript setzt möglicherweise mit session_name() einen Namen. Dann kommt session_start().

            An diesem Punkt wird nachgeschaut, ob der Client in irgendeiner Weise eine Session-ID übergeben hat. Wahlweise per Cookie, GET-Parameter oder POST-Formularfeld.

            Wenn in diesen Daten ein Parameter gefunden wird, der den aktuell von session_name() gesetzten Namen hat, wird der Parameterwert, der zugewiesen wurde, als session_id() verwendet. Das bedeutet, dass in dem temporären Verzeichnis, in dem die Session-Dateien abgelegt werden (das kann man natürlich ändern - sowohl das Verzeichnis, als auch die Tatsache, dass die Daten in einer Datei abgelegt werden - Datenbanken sind ebenso möglich), nach einer Datei gesucht wird, die "sess_SESSIONID" heißt. Wenn also eine PHP-generierte Session-ID genutzt wird, heißen solche Dateien gerne "sess_27878F27D787EBA6F..." oder so.

            Bei session_start() wird also geschaut, ob eine Datei mit passender Session-ID existiert, und wenn ja, wird ihr Inhalt in die Variable $_SESSION gepackt.

            Wenn du nun also verhindern willst, dass Leute nach Beenden der Session einfach weitermachen können, mußt du in den Session-Daten irgendwie ein Flag oder eine Information setzen, dass der Benutzer erfolgreich eingeloggt wurde. Diese Information mußt du wieder entfernen oder auf Null setzen, wenn der Benutzer sich ausloggt. Und dann natürlich bei jeder Seite, die das Login erfordert, prüfen, ob der Benutzer das Login-Kennzeichen noch gesetzt hat.

            Du kannst dich jedoch keinesfalls darauf verlassen, dass mit session_destroy() bzw. dem in PHP eingestellten Timeout der Session die Daten wirkungsvoll gelöscht würden. Das Timeout ist nämlich zusätzlich noch von einem Zufallsfaktor abhängig. Standardmäßig wird statistisch nur bei jedem hunderdsten Skriptzugriff geprüft, ob irgendwelche Sessiondateien zu alt sind. Auf einer Site mit wenig Verkehr kann eine alte Session also schon mal gern zwei Tage oder drei Wochen auf dem Server liegenbleiben. Wenn du intern dann keinen Timeout-Mechanismus eingebaut hast, kriegst du ein Problem.

            Du hast immer noch nicht genau gesagt, was nicht funktionieren soll. Das solltest du mal genau nachholen. Inkl. Codebeispiel/-ausschnitt.

            - Sven Rautenberg

            --
            "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
            (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
            1. Hallo alle zusammen,

              von einem session_destroy() wird die Session-Datei definitiv gelöscht, es sei denn, dass die Session als read-only angemeldet wurde.

              Grüße

              Tom

              1. Moin!

                von einem session_destroy() wird die Session-Datei definitiv gelöscht, es sei denn, dass die Session als read-only angemeldet wurde.

                Ja, und? Wenn der nächste Request mit der gleichen Session-ID kommt, wird die Datei wieder leer angelegt und die Session geht (vielleicht - das ist ja der Streitpunkt - mit leeren Daten) weiter.

                - Sven Rautenberg

                --
                "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
                (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
                1. Hallo Sven,

                  Ja, und? Wenn der nächste Request mit der gleichen Session-ID kommt, wird die Datei wieder leer angelegt und die Session geht (vielleicht - das ist ja der Streitpunkt - mit leeren Daten) weiter.

                  Genauso hatte ich's bereits beschrieben an irgend einer Stelle in diesem Thread...

                  Was natürlich nicht so ganz stimmte, dass die Sessionverwaltung NUR in $_COOKIE[$sessionname] nachschaut. Das hattest Du schon besser auf den Punkt gebracht.

                  Nun sollten wir das Ganze nochmal zusammentragen und in Self verewigen. Ich kann mich nämlich noch gut daran erinnern, was ich mich am Anfang schwer getan habe, weil die Szusammenhänge nirgens so klar beschrieben standen. Da habe ich auch noch drei kleine Spielscripte:

                  ------------------------
                  <?php     #### session_starten.php ####
                  session_start();

                  if (strlen(SID)>0)
                  {
                    echo "Session Nr ".SID." wurd neu gestartet<br>";
                  }

                  echo "Die aktuelle Sessionnummer lautet: ".session_id()."<br>";

                  ?>
                  <a href="session_fortsetzen.php">Session fortsetzen</a>
                  -------------------------
                  <?php     #### session_fortsetzen.php ####
                  session_start();

                  if (strlen(SID)>0)
                  {
                    echo "Session Nr ".SID." wurd neu gestartet<br>";
                  }
                  else
                  {
                    echo "Session wurde fortgesetzt.<br>".
                         "Die Sessionnummer lautet: ".session_id()."<br>";
                  }
                  ?>
                  <a href="session_killen.php">Session zerstören</a>
                  --------------------------
                  <?php     #### session_killen.php ####
                  session_start();

                  if (strlen(SID)>0)
                  {
                    echo "Session Nr ".SID." wurd neu gestartet<br>";
                  }
                  else
                  {
                    echo "Session wurde fortgesetzt.<br>".
                         "Die Sessionnummer lautet: ".session_id()."<br>";
                  }

                  session_destroy();
                  echo "Session wurde soeben beendet.<br>".
                  ?>
                  <a href="session_starten.php">Session starten</a>
                  --------------------------

                  Man könnte noch ein fileexist auf die Sessiondatei einbauen...
                  Man könnte Werte übergeben und kontrolliern ob sie drinstehen
                  Man könnte sich die Cookie-Variablen anschauen
                  Man könnte mit den ini-Parametern herumspielen
                  Man könnte die Rechte im Dateisystem verändern (Sessionverzeichnis)
                  Man könnte den Sessionnamen ändern
                  Man könnte unter dem Sessionnamen einen Eintrag in $_COOKIE machen
                  ...

                  Irgendwann mach ich mein Script doch nochmal fertig ;-)

                  Grüße

                  Tom

                  1. Moin!

                    Nun sollten wir das Ganze nochmal zusammentragen und in Self verewigen. Ich kann mich nämlich noch gut daran erinnern, was ich mich am Anfang schwer getan habe, weil die Szusammenhänge nirgens so klar beschrieben standen.

                    Als grundsätzliches Fazit muß man sagen: Nicht die Existenz einer Session darf maßgeblich für irgendwelche Aktionsmöglichkeiten (Eingeloggtsein etc.) sein, sondern deren _Zustand_, also die in den Sessiondaten gespeicherte Tatsache, ob jemand irgendwas darf.

                    Konkreter ausgedrückt:

                    • Ich kann mich beispielsweise nicht darauf verlassen, dass Sessions nach der eingestellten Zeit sofort verschwinden und gelöscht werden, sondern muß für einen Timeout immer die Zeit des letzten Zugriffs in den Sessiondaten speichern und bei jedem erneuten Zugriff prüfen, ob die Zeit schon abgelaufen ist.

                    • Ich kann ein Logout auch prima so hinkriegen, dass ich einfach ein Flag "eingeloggt" oder die Information "Username/Passwort", mit denen ich Zugriff auf die Datenbankeinträge kriegen würde, wieder gelöscht wird. Wenn danach jemand die Session wiederverwendet, und die Sessiondaten noch nicht gelöscht wurden, ist man zumindest nicht gleich eingeloggt.

                    • Beides zusammen ist ein relativ sicherer Weg, Sessions mit Logoutmöglichkeit und Timeout abzusichern.

                    session_destroy() habe ich jedenfalls noch nicht wirklich benötigt. Kann natürlich auch sein, dass ich das irgendwie nicht so richtig verstanden habe. :)

                    - Sven Rautenberg

                    --
                    "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
                    (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
      2. Hallo,

        ich erwarte von der funktion, daß sie die korrespondierende sessiondatei im php-verzeichnis löscht und somit die daten vernichtet. damit ist die aktuelle SID erledigt. außerdem führe ich an dieser stelle noch ein unset auf $_SESSION aus, um auch im speicher aufzuräumen.

        Das stimmt auch fast. Nur löscht die Funktion session_destroy() NICHT die HTML-Datei auf dem Client. Und in der steht die Session-ID dutzende Male drin. Wenn nun eine Anforderung an den Server aus dieser Datei kommt, dann steht ja im aufgerufenen Script i.d.R. gelich oben

        session_start()

        Diese Funktion schaut nun ihrerseits in der Variablen $_COOKIE[$sessionname"] nach, ob eine Sessionnummer vorhanden ist. Wenn ja, wird versucht, die Session wieder aufzunehmen. Ist die Sessiondatei aus irgend einem Grunde noch da, werden die Sessionvariablen auch wiederhergestellt. Sollte sie gelöscht sein, wird sie unter der alten Nummer neu angelegt. Dann sind die Sessionvariablen natürlich leer.

        Grüße

        Tom