modulo: Nicht noch eine Benutzerverwaltungsfrage!

Guten Morgen lieber SELFHTML'ler,

ich bin gerade dabei einen Memberbereich zu erstellen, bei dem zwischen den Benutzer unterschieden wird. Also, die meisten Informationen, die die Benutzer bekommen sind gleich aber nicht überall. Bereiche wie persönliche Daten ,individuell angepasste Seiten (eigens gewähltes Layout und/oder Content) müssen da natürlich von User zu User unterscheidbar sein.

Klar, generiere die Seiten dynamisch, d.h. nur der Content liegt in der Datenbank vor, das Layout passe ich momentan noch per Hand an. XML wird in keiner form eingesetzt und ich möchte das auch erst später einbauen (vielleicht für ein individuell angepasstes Layout). Ich benutze ein MySQL DBMS und als Skriptsprache PHP4.

Meine Idee zur Realisierung des Problems:

Anmelden und einloggen:
-Man Meldet sich an, ein Cookie wird gesetzt(enthaltene Daten: username und passwort). Später werden die Daten aus dem Cookie genommen, wenn er dann gelöscht wurde muss man sich halt einloggen und ein Cookie wird erneut gesetzt.

Im Memberbereich:

  • Auf jeder Seite wird nun der Cookie überprüft und die entsprechenden Daten bereitgestellt.

Memberverwaltung auf Webseiten ist etwas gänzlich neues für mich.

  • Meine Frage, ist das überhaupt eine adequate Lösung? Irgendwie habe ich das Gefühl, mein Lösungsansatz _schlecht_. Wie sollte ich das euer Meinung nach realisieren, was gibt es für standard Lösungen? Lasst mich von eurem Wissen/Erfahrung profitieren ;-P

Gruss, Oliver

  1. Moin,

    meiner Meinung nach wird das mit sessions realisiert...

    Gruß jakob

  2. Hi!

    Ich würde es eventuell genau so machen. Ist kein Cookie da, dann einloggen, was sonst? "Sessions" helfen m.E. nicht.

    Eventuell kann die Einstiegs-URL auch so aussehen:
    http://yourSite/cgi-bin/yourSite.pl?ACC=Account&PWD=password (So würde ich mit Perl und CGI eventuell das "Einloggen" managen)

    http unterstützt keine "Sitzungen", so dass die Sitzung logisch serverseitig evrwaltet werden muss, durch ständige Roundtrips der Sitzungs_GUID z.B.

    Gruss,
    Lude

  3. Moin!

    Meine Idee zur Realisierung des Problems:

    Anmelden und einloggen:
    -Man Meldet sich an, ein Cookie wird gesetzt(enthaltene Daten: username und passwort). Später werden die Daten aus dem Cookie genommen, wenn er dann gelöscht wurde muss man sich halt einloggen und ein Cookie wird erneut gesetzt.

    Ganz schlechte Idee. Cookies bleiben gerne mal liegen, werden ausspioniert etc... naja, auch wenns nicht ganz so krass ist: Username und Passwort würden auf diese Weise immer wieder übermittelt - viel Angriffsfläche. Deshalb löse das besser über Sessions (PHP bietet wirklich simple Funktionen dafür, die toll funktionieren). Dann speicherst du Username und Passwort nämlich in den Session-Variablen - die speichert der Server bei sich, und nicht beim User, sie kommen also nicht unbedingt in fremde Hände.

    Im Memberbereich:

    • Auf jeder Seite wird nun der Cookie überprüft und die entsprechenden Daten bereitgestellt.

    Genau. Nur dass du wieder die PHP-eigenen Session-Funktionen benutzt, um den angemeldeten Benutzer zu identifizieren. Hat er keine Anmeldung geleistet -> Weiterleitung zur Anmeldeseite. Ansonsten steht der Benutzername in den Session-Variablen, und du kannst mit dieser Information z.B. die Datenbank befragen.

    Du mußt nur grundsätzlich entscheiden: Willst du auf diese Weise _alle_ Webseiten mit einer Session verdrahten, oder nur den individuellen Bereich, für den man sich anmelden muß? Ich persönlich bin für die zweite Lösung (sofern man auch ohne Anmeldung auf die allgemeinen Seiten kommt) - Cookies erlaube ich selbst nämlich meist nie, wenn ich auf eine Seite komme.

    - Sven Rautenberg

    1. Anmelden und einloggen:
      -Man Meldet sich an, ein Cookie wird gesetzt(enthaltene Daten: username und passwort). SpÃter werden die Daten aus dem Cookie genommen, wenn er dann gelÃscht wurde muss man sich halt einloggen und ein Cookie wird erneut gesetzt.

      Ganz schlechte Idee. Cookies bleiben gerne mal liegen, werden ausspioniert etc... naja, auch wenns nicht ganz so krass ist: Username und Passwort wÃrden auf diese Weise immer wieder Ãbermittelt - viel AngriffsflÃche. Deshalb lÃse das besser Ãber Sessions (PHP bietet wirklich simple Funktionen dafÃr, die toll funktionieren). Dann speicherst du Username und Passwort nÃmlich in den Session-Variablen - die speichert der Server bei sich, und nicht beim User, sie kommen also nicht unbedingt in fremde HÃnde.

      Hallo, Sven,

      ich verstehe nicht, wie der Server bei PHP-Sessions Username und Password speichern kann. Der User muss sich doch fÃr jede "Sitzung" neu indentifizieren; erst dann gibt es doch eine Sitzungs-GUID, die, wenn ich nicht auf dem falschen Dampfer bin, hin- und hergesendet werden muss.

      Eine ErklÃrung oder ein Link zum PHP-Sitzungskonzept wÃre nett.

      Gruss,
      Lude

      1. Moin!

        ich verstehe nicht, wie der Server bei PHP-Sessions Username und Password speichern kann. Der User muss sich doch fÃr jede "Sitzung" neu indentifizieren; erst dann gibt es doch eine Sitzungs-GUID, die, wenn ich nicht auf dem falschen Dampfer bin, hin- und hergesendet werden muss.

        Eine ErklÃrung oder ein Link zum PHP-Sitzungskonzept wÃre nett.

        Ist relativ einfach: Jede Seite, die eine erfolgte Anmeldung erfordert, prÃft, ob in den Session-Variablen schon Benutzername und Passwort hinterlegt sind, und prÃft diese Angaben in der Datenbank.

        Vollkommen unabhÃngig davon kriegt ein Besucher beim ersten Seitenkontakt eine Session-ID verpaÃt. Solange er keine geschÃtzte Seite aufruft, ist das belanglos (er wird nur besser identifizier- und verfolgbar). Wenn er sich einloggen will, stellt das System fest, dass noch kein Benutzername und Passwort gespeichert wurden - also muà das System danach fragen -> Loginmaske kommt. Der Besucher gibt die Daten ein, das System speichert sie in der Session und kann mit diesen Angaben jetzt auf jeder Seite die Authentifizierung durchfÃhren. Die Session-ID, die bei jedem Seitenzugriff geliefert wird, ist praktisch zum Ersatzbegriff fÃr Username und Passwort geworden.

        Immer wenn das System feststellt, dass Username und Passwort nicht zu einem registrierten User gehÃren, erscheint die Login-Maske zur Eingabe gÃltiger Authentifizierungsdaten. So erreicht man, dass sich dumme User auch mal vertippen dÃrfen. Mit geschickter Anwendung von URL-Mapping kann man die Sache sogar so aufpeppen und hinkriegen, dass angemeldete Besucher auf die jeweiligen gesicherten Seiten Bookmarks legen kÃnnen - im unangemeldeten Zustand kriegen sie dann eine Loginseite angeboten, auf der sie sich anmelden mÃssen, und gelangen dann automatisch zur jeweiligen gewÃnschten Seite - man muà die Leute nicht zwingend Ãber eine zentrale Anmeldeseite leiten.

        - Sven Rautenberg

        1. Hallo Sven,

          Ist relativ einfach: Jede Seite, die eine erfolgte Anmeldung erfordert, prÃft, ob in den Session-Variablen schon Benutzername und Passwort hinterlegt sind, und prÃft diese Angaben in der Datenbank.

          Ich bin in Sachen Sessions auch Anfängerin, aber meines Erachtens kannst du durchaus festlegen, was in der Session gespeichert wird und was nicht. Ich hatte das bislang eigentlich so verstanden:

          Ich habe in einer Datenbank Infos zu meinen registrierten Nutzern und deren Gruppenzugehörigkeiten.
          Meine Seiten verfügen über die Information, welche User respektive Gruppen sie angucken dürfen. Wenn die Seite nicht für die Allgemeinheit offen ist, benötigt sie ein
          session_start();
          Nehmen wir jetzt an, ein bislang nicht angemeldetes Userlein stößt auf eine solche Seite.
          Dann kann ich doch abfragen:
          if(!$_SESSION['user']) ab zur login-Seite.
          Auch die login-Seite hat ein session_start(). Auf diese geht jetzt mein Userlein und meldet sich an.
          Username und Passwort werden (letzteres vielleicht verschlüsselt) übertragen, sind aber noch nicht als Session-Variablen registriert.
          Nachdem die Anmelde-Daten angekommen sind, lasse ich das gegen meine Datenbank rennen und gucke, obs den User überhaupt gibt. Wenn ja erzeuge ich vielleicht ein Objekt der Klasse clsUser, und speichere dort den Usernamen, seine Gruppenzugehörigkeiten etc., sprich alles, was ich für den weiteren Betrieb brauche. Das Passwort gehört nicht dazu.
          also $currUser = new clsUser();
          $currUser->usrName = der Username;
          $currUser->usrGrps = array(die,gruppen,wie,sie,aus,der,datenbank,kommen)

          Nachdem ich dieses Objekt nun erzeugt habe, registriere ich diese Variable im $_SESSION-Array.
          $_SESSION["user"] = $currUser;

          Geht mein erfolgreich angemeldetes Userlein wieder auf eine geschützte Seite, fragt die halt nur noch diese Session-Variable ab:
          if(!$_SESSION["user"]) {
            ab zur login-Selte
          } else {
            hat Userlein ausreichend Rechte, um die fragliche Seite zu sehen.
          }

          Also wird das Passwort doch nur ein einziges Mal übertragen. Oder bin ich da jetzt fundamental im Irrtum?

          Liebe Grüße, Uschi

          1. Hallo Uschi,

            Also wird das Passwort doch nur ein einziges Mal
            übertragen.

            Richtig. Und wenn im Cookie nicht das Passwort, sondern statt dessen die Session-ID steht, dann dort ebenfalls.

            Der einzige Unterschied zwischen diese beiden Fällen ist, daß der URL mit der Session-ID leichter beobachtet (Logfiles) und leichter angewendet (ggf. einfach in die Location-Zeile kopieren und ein bißchen darin herum stochern) werden kann als der Cookie, der normalerweise weder geloggt wird noch von einem normalen Browser-Benutzer erzeugt werden kann.
            Von einem Cracker mit Programm wie http://www.schroepl.net/cgi-bin/http_trace.pl als Pseudo-Browser, welches HTTP-Header aktiv zusammenbastelt, kann auch so ein Request mit Cookie natürlich gefaked werden - wenn er weiß, was in dem Cookie stehen muß - eventuelle Prüfsummen mit Bezug auf andere HTTP-Header, etwa seine IP-Adresse, innerhalb des Cookie-Wertes würden ihm allerdings weh tun können.

            Oder bin ich da jetzt fundamental im Irrtum?

            Du hast das schon alles richtig verstanden, denke ich.

            Viele Grüße
                  Michael

    2. Hi Sven,

      Ganz schlechte Idee. Cookies bleiben gerne mal
      liegen, werden ausspioniert etc... naja, auch wenns
      nicht ganz so krass ist: Username und Passwort
      würden auf diese Weise immer wieder übermittelt -
      viel Angriffsfläche.

      wieso denn das? Wer wird denn das Passwort in den Cookie hinein schreiben?

      In den Cookie schreibt man eine Session-Nummer, die serverseitig vergeben und gespeichert wird.
      Bei jedem Zugriff kann der Cookie dann nicht nur auf Existenz geprüft, sondern auch sein Inhalt validiert werden - und das ohne Passwort. Auf diese Weise kann man insbesondere auch paralleles Login derselben Benutzerkennung erkennen und verhindern, wenn man will. Man tut einfach genau das, was eine Session-Verwaltung von PHP auch tut.

      Diese Art der Cookie-Verwendung ist gerade sicherheitstechnisch deutlich besser als die ansonsten gerne bemühte Server Authentication - _die_ sendet nämlich wirklich Benutzername und Passwort bei jedem Zugriff (und das zudem auch noch unverschlüsselt, denn wer kann es sich schon leisten, "AuthType Digest" zu nehmen und Netscape 6 auszuschließen?).

      Deshalb löse das besser über Sessions (PHP bietet
      wirklich simple Funktionen dafür, die toll
      funktionieren).

      PHP transportiert seine Session-Informationen allerdings vermutlich im URL und deshalb sind diese Informationen nicht nur in allen Logs, sondern vor allem auch in Referer-Headern enthalten!
      Nichts von beidem ist der Fall, wenn Cookies eingesetzt werden.

      Ja, ich weiß, daß manche Leute Cookies nicht mögen - aber technisch gesehen sind sie für diesen Fall wirklich der beste verfügbare Mechanismus, sofern sie von der Aufgabenstellung nicht grundsätzlich ausgeschlossen wurden.

      Cookies erlaube ich selbst nämlich meist nie, wenn
      ich auf eine Seite komme.

      Würdest Du auch so argumentieren, wenn Du für den unter Verwendung von Cookies angebotenen Dienst aufgrund von dessen Inhalten viel Geld zu bezahlen bereit bist?
      Banken beispielsweise akzeptieren Cookies in einem solchen Fall ...

      Viele Grüße
            Michael

      1. Hallo Michael,

        wieso denn das? Wer wird denn das Passwort in den Cookie hinein schreiben?

        Ich nicht, Du nicht, Sven nicht, aber der, der die Frage gestellt hat, schon.

        PHP transportiert seine Session-Informationen allerdings vermutlich im URL und deshalb sind diese Informationen nicht nur in allen Logs, sondern vor allem auch in Referer-Headern enthalten!
        Nichts von beidem ist der Fall, wenn Cookies eingesetzt werden.

        Nein, PHP transportiert die Session-Informationen in der URL *oder* im Cookie, je nachdem, was der Benutzer versteht. Das funktioniert so: beim session_start wird erst mal das Cookie gesetzt. Falls in den Cookies keine Session-ID nicht auftaucht, wird davon ausgegangen, dass der User keine Cookies mag. Dann werden URLs automatisch umgeschrieben. (sofern url-rewriting aktiviert ist) Wenn der Benutzer Cookies akzeptiert, dann wird die URL halt nur beim ersten Mal umgeschrieben, beim zweiten mal nicht. Ich persönlich schalte URL-Reweriting aber lieber per ini_set vor session_start aus, da ich den Server nicht unnötig belasten will. Die Schreibarbeit bei den Links lohnt sich, denn wenn PHP jedesmal vor der Auslieferung die Seite parsen muss, kostet das wirklich Rechenpower und Zeit. Vor allem aber ersetzt das URL-Rewriting AFAIK nicht so sonderfälle wie Location-Header o.ä.

        Zum Referer-Problem: GMX zum Beispiel schaltet noch eine Seite davor, bevor man auf einen Link klickt, damit gerade so etwas vermieden wird. Dass das aber auch Nachteile im Bereich Datenschutz hat, ist klar. Vielleicht wäre es eine Lösung, die Seite nur davorzuschalten, wenn im _aktuellen_ Query-String des Scripts, das den Link ausgibt, die Session-ID vorkommt - und wenn sie nicht vorkommt, dann ist der Referer auch kein Problem.

        Grüße,

        Christian

        1. Hallo Christian, hallo Michael,

          Ich muß mal ein paar Fragen fragen, büdde :-))

          Nein, PHP transportiert die Session-Informationen in der URL *oder* im Cookie, je nachdem, was der Benutzer versteht.

          Gehe ich recht in der Annahme, dass zunächst ausprobiert wird, ob der User Cookies zuläßt und dann kommt die URL an die Reihe?

          Das funktioniert so: beim session_start wird erst mal das Cookie gesetzt.

          Wohin wird dieses Cookie gesetzt? Beim Client, oder? Und wenn der keine Cookies zulässt, wird auch keins gesetzt, geht ja nicht. Wäre die korrekte Formulierung: "Bei session_start() wird versucht, ein Cookie zu setzen"?

          Falls in den Cookies keine Session-ID nicht auftaucht, wird davon ausgegangen, dass der User keine Cookies mag. Dann werden URLs automatisch umgeschrieben. (sofern url-rewriting aktiviert ist).

          Heisst das, PHP guckt in dem superglobalen Array $_COOKIE nach, ob in $_COOKIE["PHPSESSID"] oder wie immer der Name für die SessionID auch lautet, mit einem brauchbaren Wert versehen ist?

          Wenn der Benutzer Cookies akzeptiert, dann wird die URL halt nur beim ersten Mal umgeschrieben, beim zweiten mal nicht. Ich persönlich schalte URL-Reweriting aber lieber per ini_set vor session_start aus, da ich den Server nicht unnötig belasten will.

          Die Schreibarbeit bei den Links lohnt sich, denn wenn PHP jedesmal vor der Auslieferung die Seite parsen muss, kostet das wirklich Rechenpower und Zeit. Vor allem aber ersetzt das URL-Rewriting AFAIK nicht so sonderfälle wie Location-Header o.ä.
          Der vorstehende Absatz ist mir ein Buch mit sieben Giebeln:

          1. Wenn du via ini_set das URL_Rewriting abschaltest, muss dein User Cookies erlauben, oder die gesamte Autentifizierung funktioniert überhaupt nicht. Richtig oder falsch?

          2. Meinst du mit Schreibarbeit bei den Links, dass du bei den Links, wo du mit Session-Variablen arbeitest, diese in dem Fall, dass der User cookies nicht erlaubt, halbautomatisch anhängst.
            Also in etwa so:
            $url = "/link/auf/eine/interne/datei.php";
            if(!$COOKIE["PHPSESSID"]) {
              $url .= "?id=" .session_id();
            }

          Und wenns nach draussen geht, dann läßt du die sessionID eben weg? Und ebenfalls dann, wenn der Link auf eine interne Seite (.php) geht, bei der keine Sessions benötigt werden?

          Zum Referer-Problem:

          Gehe ich recht in der Annahme, daß das Referer-Problem darin besteht, daß im Falle eines automatischen URL-rewritings durch PHP die session_id auch an eine fremde URL weitergeben würde?

          GMX zum Beispiel schaltet noch eine Seite davor, bevor man auf einen Link klickt, damit gerade so etwas vermieden wird. Dass das aber auch Nachteile im Bereich Datenschutz hat, ist klar. Vielleicht wäre es eine Lösung, die Seite nur davorzuschalten, wenn im _aktuellen_ Query-String des Scripts, das den Link ausgibt, die Session-ID vorkommt - und wenn sie nicht vorkommt, dann ist der Referer auch kein Problem.

          Ich habe noch nie verstanden, warum GMX diese nervige Seite dazwischen hat. Nun weiß ich, es hat mit sessions zu tun, aber verstanden habe ich es nicht :-(((

          Liebe Grüße, Uschi
          (PS: mit den header-geschichten habe ich mich bislang gar nicht auseinandergesetzt. ich schätze, ich sollte das mal tun?)

          1. Moin,

            Gehe ich recht in der Annahme, dass zunächst ausprobiert wird, ob der User Cookies zuläßt und dann kommt die URL an die Reihe?

            Ja, wenn beim ersten Aufruf kein Session-Cookie gesetzt ist, wird versucht ein Cookie zu setzen und das URL-Rewriting wird aktiviert. Bei nachfolgenden Seitenaufrufen ist dann entweder das Cookie gesetzt und URL-Rewriting wird abgeschaltet oder aber die Session-ID ist über den URL-Parameter bekannt und es wird weiter lustig rewriting gemacht.

            Heisst das, PHP guckt in dem superglobalen Array $_COOKIE nach, ob in $_COOKIE["PHPSESSID"] oder wie immer der Name für die SessionID auch lautet, mit einem brauchbaren Wert versehen ist?

            So in etwa.

            Der vorstehende Absatz ist mir ein Buch mit sieben Giebeln:

            1. Wenn du via ini_set das URL_Rewriting abschaltest, muss dein User Cookies erlauben, oder die gesamte Autentifizierung funktioniert überhaupt nicht. Richtig oder falsch?

            Die Sessions funktionieren dann nicht, wenn du nicht selber an den richtigen Stellen die Session-ID im URL mitschleppst, richtig.

            1. Meinst du mit Schreibarbeit bei den Links, dass du bei den Links, wo du mit Session-Variablen arbeitest, diese in dem Fall, dass der User cookies nicht erlaubt, halbautomatisch anhängst.
              Also in etwa so:
              $url = "/link/auf/eine/interne/datei.php";
              if(!$COOKIE["PHPSESSID"]) {
                $url .= "?id=" .session_id();
              }

            So in etwa.

            Und wenns nach draussen geht, dann läßt du die sessionID eben weg? Und ebenfalls dann, wenn der Link auf eine interne Seite (.php) geht, bei der keine Sessions benötigt werden?

            Ja. Ja.

            Gehe ich recht in der Annahme, daß das Referer-Problem darin besteht, daß im Falle eines automatischen URL-rewritings durch PHP die session_id auch an eine fremde URL weitergeben würde?

            Ja.

            Ich habe noch nie verstanden, warum GMX diese nervige Seite dazwischen hat. Nun weiß ich, es hat mit sessions zu tun, aber verstanden habe ich es nicht :-(((

            Du hast dich am Anfang bei GMX eingeloggt und eine Session-ID bekommen. So lange die Sitzung läuft (== bis du auf Logout klickst oder der timeout zuschlägt) kann _jeder_ der im Besitz dieser Session-ID ist, deine aktuelle Sitzung benutzen, ganz genau so, als ob er sich bei GMX als du eingeloggt hätte. Er könnte deine Mails lesen, löschen, unter deinem Absender selbst welche verschicken, lustig in den von dir angegebenen persönlichen Daten rumstöbern (deine Post-Addresse etwa oder auch das Addressbuch) und wahrscheinlich auch das Passwort ändern.

            Innerhalb von GMX hängt die Session-ID an allen Seiten dran die du aufrufst. Wenn du jetzt von dort aus einem Link folgst oder dein Browser ein Bild/Stylesheet/sonstwas lädt, wird er mit sehr hoher Wahrscheinlichkeit den kompletten URL der aktuellen Seite (mit Session-ID!) als Referer: senden. Würdest du also von dort aus Ressourcen von ausserhalb GMX direkt aufrufen, würde der jeweilige Server mit sehr hoher Wahrscheinlichkeit deine Session-ID erfahren und könnte dann alles im vorangegangenen Absatz gesagte tun.

            --
            Henryk Plötz
            Grüße aus Berlin

            1. Hallo Henryk,

              und wahrscheinlich auch das Passwort ändern.

              Nein, GMX verlangt *zum Glück* immer das alte Passwort, wenn man irgendeine sicherheitsrelevante Einstellung ändert. Dazu zählen: Das Passwort selbst, die Handynummer und die Email, an die eine URI versand wird, falls man das Passwort vergessen hat. Wäre das nicht der Fall, hätte ich schon längst "gekündigt".

              Grüße,

              Christian

              1. Moin,

                Nein, GMX verlangt *zum Glück* immer das alte Passwort, wenn man irgendeine sicherheitsrelevante Einstellung ändert.

                Oh, du hast Recht. Ich kann mich dunkel erinnern, dass vor langer, langer Zeit als ich mich da angemeldet habe, als zweiter Authentifizierungsweg eine Geheimfrage mit Antwort gedient hat und man diese im Klartext über das Webinterface ändern konnte. Ich dachte, das würde man notfalls ausnutzen können, wenn man Zugang zur Sitzung hat, aber das scheint es tatsächlich nicht mehr zu geben (oder ich habe mir das eingebildet).

                Mir ist bei der Gelegenheit aber eine Ungereimtheit aufgefallen, auf die ich die GMXler erst einmal ansprechen möchte, bevor ich Näheres sage.

                --
                Henryk Plötz
                Grüße aus Berlin

  4. Vielen Dank,

    ihr habt mir sehr weitergeholfen. Auf Grundlage der Informationen die ich von euch habe, werde ich das nun realisieren.

    Gruss, Oliver