lska: Wie funktioniert Einloggen mit Sessions?

Habe jetzt ein sehr einfaches php-basiertes Registrierungssystem mit Login-Form aufgesetzt. Kann mir jemand erklären wie man das mit Sessions einbauen kann?

  1. Hallo,

    Habe jetzt ein sehr einfaches php-basiertes Registrierungssystem mit Login-Form aufgesetzt. Kann mir jemand erklären wie man das mit Sessions einbauen kann?

    Das kann dir sicher jemand erklären, aber nicht hier im Einzelunterricht.

    -> Google: PHP Sessions Tutorial

    Mathias

    1. ...bin etwas altersmilde...

      Du hast eine Loginform und ich nehme an ein serverseitiges Script, was feststellt, ob der Mensch die richtigen Daten eingegeben hat. In dem Moment, wo Du entscheidest, dieser Mensch ist verifiziert, musst Du zwei Informationen speichern: a) der Mensch ist eingeloggt. b) wer dieser Mensch ist.

      Es eignet sich daür Sessionvariablen zu nutzen. Sie sind von Aufruf zu Aufruf für Dich in php verfügbar. Dabei muss natürlich von Aufruf zu Aufruf erst einmal definiert sein. Warum sind zwei Aufrufe Deiner Website miteinander verknüpfbar? Wegen der SessionID! Diese wird bei session_start(); automatisch erzeugt. Abhängig von den Servereinstellungen und von den Usereinstellunge wird diese im Idealfall im Cookie gespeichert und automatisch bei jedem Aufruf mitgesendet. Gehen wir mal davon aus. Für weiteres musst Du Dich tiefer einlesen.~~~php

      <?php

      session_start();

      if($du_hast_entschieden_das_der_user_korrekte_einlogdaten_gegeben_hat){
        $_SESSION["user_id"] = $user_id;
        $_SESSION["user_verified"] = TRUE;
      }

      ?>

        
      Dann kannst Du immer auf diese Variablen zugreifen.  
        
      ~~~php
      <?php  
        
      if($_SESSION["user_verified"]){  
        echo "zeige geheimen content (nicht geheim genug für die NSA, though) ";  
      }  
        
      ?>
      

      Cheers,
      Baba

  2. Hello,

    Habe jetzt ein sehr einfaches php-basiertes Registrierungssystem mit Login-Form aufgesetzt. Kann mir jemand erklären wie man das mit Sessions einbauen kann?

    Hast Du das Script nun schon, oder möchtest Du es von uns haben?
    Zeig doch einfach mal, was Du schon hast.

    Grundsätzlich sollte man unterscheiden, ob man das "Login" sessionbaisrt oder requestbasiert aufbauen will. Für eine requestbasierte Ausführung (meine Empfehlung) benötigst Du eine zusätzliche gemeinsame Datenbasis für alle User desselben Systems, vornehmlich eine oder mehrere Tabellen in einer Datenbank.

    Das hat dann auch den Vorteil, dass man sowas, wie "wer ist Online" (also, welcher User hatte in den letzten x Sekunden einen Request) leicht ermöglichen kann und dass man User auch _vor__Ablauf_ ihrer Session leicht rausschmeißen kann, wenn sie einen nerven :-)

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://restaurant-zur-kleinen-kapelle.de
    1. Hallo Tom,

      bin zwar nicht der mit der Einstiegsfrage, aber mich würde das von dir bevorzugte requestbasierte Loginsystem weiter interessieren?

      Was genau ist darunter zu verstehen?

      Ich habe z.B. eine MySQL-Tabelle mit id, name, password. Jetzt kommt wer und loggt sich ein. Ich vergleiche seine Eingaben mit  denen in der Tabelle. Wie geht es dann weiter, wenn es passt? Wo speichere ich, dass der User eingeloggt ist? Gebe ich die Logininformationen einfach per Post von Seite zu Seite weiter? Marker ich in der Tabelle einen aktiven Nutzer (bspw. mit einer weiteren Spalte "aktiv")?

      Viele Grüße
      Alex

      1. Hello Alex,

        bin zwar nicht der mit der Einstiegsfrage, aber mich würde das von dir bevorzugte requestbasierte Loginsystem weiter interessieren?

        Was genau ist darunter zu verstehen?

        Ich habe z.B. eine MySQL-Tabelle mit id, name, password. Jetzt kommt wer und loggt sich ein. Ich vergleiche seine Eingaben mit  denen in der Tabelle. Wie geht es dann weiter, wenn es passt? Wo speichere ich, dass der User eingeloggt ist? Gebe ich die Logininformationen einfach per Post von Seite zu Seite weiter? Marker ich in der Tabelle einen aktiven Nutzer (bspw. mit einer weiteren Spalte "aktiv")?

        Du benötigst als Basis des Ganzen nach wie vor eine (gültige) Session.
        Die Gültigkeitsdauer der Sessiondatei (deren Existenz) sollte LOGIN_MAX + x Sekunden betragen, also auf jeden Fall länger sein, als die vorgesehene maximale "Loginzeit" ohne Retrigger, also ohne Request des Users.

        Bei jedem Request des Users wird eine Datenbankabfrage vorgenommen, ob dort die Sessionnummer eingetragen ist mit gültigen Grenzen für Last-Request-Time, This-Request-Time und Max-Login-Time und wenn Du willst, auch noch First-Login-Time

        Dies erfordert mindestens zwei Funktionen:

        • login()
        • is_logged()

        Die könnten in etwa so aussehen:

          
          
        #------------------------------------------------------------------------------------------------------  
        function login()  
        {  
            $con = get_db_con(true);  
            $logout = logout();  
        	  
        	if (!session_regenerate_id ()) return false;  
        	  
        # die('Function login(), Connection: ' . (htmlspecialchars(print_r($con,1)))); ## fehlt ...  
          
        	if (!$con) return false;  
        	  
        	$qry_login = "update `login`  
                set  
        			session = '" . session_id() . "',  
                    lastclick = now(),  
                    sessionstart = now(),  
        			clickcount = clickcount + 1  
                where  
                    nickname = '" . mysqli_real_escape_string($con, $_POST['data']['nickname'])."' and  
                    password = '" . md5($_POST['data']['password'])."' and  
                    status > 0";  
          
        	$res = mysqli_query($con, $qry_login);		  
          
        	  
        #	die('Function login(), MySQL-Error: ' . mysql_error($con));	  
        	  
        	  
            if (mysqli_affected_rows($con) == 1)  
            {  
               $_SESSION['nickname'] = $_POST['data']['nickname'];  
        	   $_SESSION['sess_start'] = get_time();  
        	   $_SESSION['lastclick'] = get_time();  
          
               return 'Angemeldet als ' . htmlspecialchars($_SESSION['nickname']);  
            }  
            	  
            return false;  
        }  
          
        #------------------------------------------------------------------------------------------------------  
        function is_logged()  
        {  
            $con = get_db_con(true);  
          
        	if (!$con) return false;  
          
        	$qry_is_logged = "  
                update `login`  
                set  
        			lastclick = now(),  
        			clickcount = clickcount +1  
                where  
                    session = '" . session_id() . "' and  
                    (now() - lastclick < " . SESS_MAXTIME . ")";  
          
        	$res = mysqli_query($con, $qry_is_logged);		  
          
            if (mysqli_affected_rows($con) === 1)  
            {  
        		$_SESSION['lastclick'] = get_time();  
        		return htmlspecialchars($_SESSION['nickname']);  
            }  
        	elseif (mysqli_affected_rows($con) === -1)  
        	{  
        		return 'Is_logged(): Fehler im Update-Statement';  
        	}  
         	  
            return false;			  
        }  
          
          
        
        

        und ggf. noch eine dritte fürs "Logout"

          
          
        #------------------------------------------------------------------------------------------------------  
        function logout()  
        {  
            $con = get_db_con();  
        	if (!$con) return false;  
        	  
        	$qry_logout = "  
        		update `login`  
                set  
        			session = '" . 'invalid:'.get_time() ."',  
                    lastclick = 0,  
        			clickcount = clickcount +1  
                where  
        			session = '" . session_id() ."'";  
          
        	$res = mysqli_query($con, $qry_logout);		  
          
            if (mysqli_affected_rows($con) === 1)  
            {  
        	   unset($_SESSION['starttime']);  
           	   $_SESSION['sess_end'] = get_time();  
               $_SESSION['lastclick'] = get_time(); 	  
          
               return htmlspecialchars($_SESSION['nickname']) . ' wurde erfolgreich abgemeldet.';  
            }  
        	  
        	return false;  
        }  
          
          
        
        

        Dieses Verfahren hat dann den Vorteil, dass man den User auch während einer Session "rausschmeißen" kann, denn das ist meistens notwenig, wenn Verfehlungen festgestellt werden.

        Die "PHP-SESSION" würde sich ja sonst endlos verlängern mit jedem Request.

        Und man kann eine "Wer ist online"-Liste erzeugen:

          
          
        function who_is_online()  
        {  
            # static $time, $_online_list;   ## nur einmal pro Sekunde neu aufbauen!  
          
        ###### Baustelle  
        	  
            $con = get_db_con(true);  
        	if (!$con) return false;  
          
            $qry_who_is_online = "  
                select  
        			id,  
        			now() - lastclick as seconds,  
        			nickname,  
        			lastname,  
        			firstname,  
        			email  
        		from `login`  
        		where  
        			now() - lastclick < " . SESS_MAXTIME ."  
        		order by seconds";  
          
        	$res = mysqli_query($con, $qry_who_is_online);		  
          
        	if ($res)  
        	{  
        		$_online_list = false;  
        		$no = 1;  
        		while ($_record = mysqli_fetch_assoc($res))  
        		{  
        			$_online_list['id'][$no] = $_record['id'];  
        			$_online_list['nickname'][$no] = $_record['nickname'];  
        			$_online_list['seconds'][$no] = $_record['seconds'];  
        			$_online_list['lastname'][$no] = $_record['lastname'];  
        			$_online_list['firstname'][$no] = $_record['firstname'];  
        			$_online_list['email'][$no] = $_record['email'];  
        			$no++;  
        		}  
          
                return $_online_list;  
        	}  
        	  
            return false;  
        }  
          
        
        

        Ich hatte da neulich selber ein paar Fragen hinterlassen zur obigen Baustelle, da das "who is online" nicht bei jedem Request jedes Users neu aufgebaut werden müsste, sondern nur z. B. einmal pro Sekunde für das gesamte System.

        Die MySQL-Tabelle sieht bisher so aus (noch nicht weiter überprüft):

          
          
        CREATE TABLE `login` (  
          `id` int(11) NOT NULL AUTO_INCREMENT,  
          `lastclick` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  
          `clickcount` bigint(20) NOT NULL,  
          `createdate` datetime NOT NULL,  
          `sessionstart` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
          `session` varchar(50) NOT NULL,  
          `lastupdate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
          `nickname` varchar(50) NOT NULL,  
          `lastname` varchar(50) NOT NULL,  
          `password` varchar(50) NOT NULL,  
          `firstname` varchar(50) NOT NULL,  
          `email` varchar(50) NOT NULL,  
          `status` int(11) NOT NULL DEFAULT '0',  
          `level` int(11) NOT NULL DEFAULT '0',  
          PRIMARY KEY (`id`),  
          UNIQUE KEY `nickname` (`nickname`),  
          UNIQUE KEY `session` (`session`)  
        ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8  
          
        
        

        "AUTO_INCREMENT=3" steht hier nur exemplarisch.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://restaurant-zur-kleinen-kapelle.de
        1. Hello,

          Die Gültigkeitsdauer der Sessiondatei (deren Existenz) sollte LOGIN_MAX + x Sekunden betragen,

          Das sollte "SESS_MAXTIME" heißen, wie im Funktionen-Beispiel auch eingesetzt und es ist eine selbst definierte Konstante!

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://restaurant-zur-kleinen-kapelle.de
        2. Om nah hoo pez nyeetz, Tom!

          Und man kann eine "Wer ist online"-Liste erzeugen:

          Ich würde aber jeden Nutzer selbst entscheiden lassen, ob er seinen online-Status für jedermann sichtbar haben möchte, etwa über ein visibility-flag.

          Matthias

          --
          Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Verdi und Verdienstausfall.

          1. Hello,

            Und man kann eine "Wer ist online"-Liste erzeugen:

            Ich würde aber jeden Nutzer selbst entscheiden lassen, ob er seinen online-Status für jedermann sichtbar haben möchte, etwa über ein visibility-flag.

            Ja, das kann man ja machen. Dies ist ja nur eine Grundlage.
            Und ob diese zusätzlichen Userdaten dann auch in der "Login-Tabelle" stehen sollten, ist ja ohnehin fraglich. Das hatten wir hier schon diskutiert. Man kann das Ganze beliebig aufbauschen.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://restaurant-zur-kleinen-kapelle.de
        3. Hallo Tom,

          Du benötigst als Basis des Ganzen nach wie vor eine (gültige) Session.

          Gut, das war nämlich der Punkt, der mich zu meiner Frage geführt hat. Dachte du kommst in der requestbasierten Variante ohne Sessions aus.

          Vielen Dank, dass du das Beispiel so ausführlich dargelegt hast. Ich werde darauf zurückgreifen, wenn ich endlich mal die Zeit finde, meine Login zu überarbeiten.

          Freundliche Grüße
          Alex

          1. Hello Alex,

            Du benötigst als Basis des Ganzen nach wie vor eine (gültige) Session.

            Gut, das war nämlich der Punkt, der mich zu meiner Frage geführt hat. Dachte du kommst in der requestbasierten Variante ohne Sessions aus.

            Die Session ist der Mechanismus, mit dem Du den Client _identifizieren_ kannst, also wiedererkennen kannst, dass ein Requestor von vor x Sekunden nun erneut eine Anfrage stellt.

            Das "Login" ist der Mechanismus. mit dem due den Client _authentifizieren_ kannst, also feststellen kannst, welche Rechte ihm zugeordnet werden. Dazu bedarf es i . d. R. immer zweier Kriterien, nämlich Schlüssel und Gegenschlüssel, also z.B. Name und Passwort.

            Die sollten aber im Netzen nicht bei jedem Request (gemeinsam) übertragen werden (nach Möglichkeit auch nicht über eine unverschlüsselte Leitung!). Zum "Einloggen" wird dies aber üblicherweise (leider) so gemacht.

            Man könnte den "Einlogvorgang" auch auftrennen in

            • Besorgen einer Session
            • Übertragen des Namens
            • Übertragen des Passwortes

            Das würde das Mitschneiden schon um einiges schwieriger machen. Man müsste dann mindestens zwei passende Pakete (Sessionnummer und Name + Sessionnummer und Passwort) abfangen und zusammenführen.

            In den Tagged Networks, die wir inzwischen haben, wird dies den Behörden und Diensten zwar kaum Probleme machen, denn die haben ja auch Zugriff auf das Tagging, also die Kennzeichnung, von welchem Port Pakete versandt worden sind. Aber der "normale Lauscher" wird mangels Tagging-Informationen nichts mehr damit anfangen können.

            Darum muss man bei Google, eBay, usw. ja auch sein altes Passwort nochmals eingeben, wenn man ein neues setzen will. Der Loginname wird in diesem Request üblicherweise nicht mit übertragen.

            Da sie Session "flüchtig" ist, also nur eine eingeschränkte Gültigkeitsdauer hat, sind die Kombinationen von Sessionnummer und Passwort und Sessionnummer und Name also auch irgendwann hinfällig.

            Ein Hacken des Zuganges (per Name+Passwort-Versuche) müsste also innerhalb eines eng umgrenzbaren Zeitrahmens geschehen.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://restaurant-zur-kleinen-kapelle.de
    2. Hallo,

      sessionbaisrt

      ich hätte es gern baiser-basiert, ist das auch möglich?

      scnr
      Kalk

      1. Hello,

        sessionbaisrt

        ich hätte es gern baiser-basiert, ist das auch möglich?

        geht auch.

        Dafür brauchst Du dann aber das neue Windows-WAhN-3.0, das ist besonders kundenorientiert und wirft bei wiederholtem OS-Missbrauch mit Schaum-Baisers (bei Windows werden doch alle unnötigen Oprationen doppelt ausgeführt :-O )

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://restaurant-zur-kleinen-kapelle.de
  3. Om nah hoo pez nyeetz, lska!

    Habe jetzt ein sehr einfaches php-basiertes Registrierungssystem mit Login-Form aufgesetzt. Kann mir jemand erklären wie man das mit Sessions einbauen kann?

    http://wiki.selfhtml.org/wiki/Technische_Ergänzungen/Loginsystem

    Matthias

    --
    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Hund und Hundertwasser.