Tom: Wie funktioniert Einloggen mit Sessions?

Beitrag lesen

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