Memberbereich mit PHP erstellen. Das Tutorial fuer Anfaenger.

Heute möchte ich mal allen Neulingen in PHP erklären, wie man einen Memberbereich mit Login und allem drum und dran erstellt.

Voraussetzungen


Ihr solltet euch schon ein wenig mit PHP befasst haben. Ausserdem solltet ihr HTML und CSS beherrschen. Dazu eine Umgebung, auf der ihr PHP ausführen könnt. Auch wird in diesem Tutorial mit MySQL gearbeitet. Ihr solltet mindestens eine Tabelle in PhpMyAdmin erstellen können.

Legen wir los!

Als erstes brauchen wir eine Loginpage. Also ein Formular auf dem wir uns einloggen können. Bei mir sieht das so aus:

<h1>Bitte anmelden</h1>
 
 
<!-- Das Loginformular: -->
<form action="loginVer.php" method="post">
 
<table border="0">
<tbody>
<tr>
<td>Loginname:</td>
<td>
<input maxlength="20" name="nick" type="text" /></td>
</tr>
<tr>
<td>Passwort:</td>
<td>
<input maxlength="20" name="pass" type="password" /></td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" /></td>
</tr>
</tbody>
</table>
 
</form>

Ich denke, dazu muss ich nichts sagen.

So, als nächstens erstellen wir die Tabelle “User” in MySQL. Am besten geht das mit PhpMyAdmin.

Die Tabelle soll User heissen. Darin brauchen wir vier Felder: UserID, Nick, Passwort und Session. Wir kommen später nochmals darauf zurück.

Wer es schnell haben möchte, kann auch dies bei sich unter dem Punkt “SQL” in PhpMyAdmin eintragen:

CREATE TABLE `User` (
  `UserID` bigint(11) NOT NULL auto_increment,
  `Nick` varchar(20) NOT NULL,
  `Passwort` varchar(100) NOT NULL,
  `Session` varchar(100) NOT NULL,
  PRIMARY KEY  (`UserID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

Die zweite Datei die wir benötigen, ist die “loginVer.php” (wie ihr sicher schon erraten habt :P ). In dieser Datei werden wir die Eingaben überprüfen, und in der Datenbank schauen ob alle Daten existieren und stimmen. Wenn alles richtig ist, wird dem User “eintritt” gewährt. Natürlich müssen wir danach auf jeder Seite noch überprüfen, ob der User sie sehen darf. Aber dazu kommen wir dan auch noch.

Hier ein Codeschnippsel aus “loginVer.php”:

	//Diese Variable wird auf "1" gesetzt, sobald ein Fehler auftreten sollte.
	$err = 0;
	//wurde etwas in das Formular geschrieben?
	if($_POST["nick"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte tragen Sie den Nicknamen ein!");
	}
	if($_POST["pass"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte geben Sie ihr Passwort ein!");
	}

Und nun die Erklärung. Als erstes setze ich eine Variable ($err). Diese ist 0, und zwar solange kein Fehler auftritt. Danach überprüfe ich die zwei Felder, die man auf unserer Loginseite ausfüllen kann. Sind diese Null, wird die Variable $err auf eins gesetzt, und ein Fehler ausgegeben.

So, jetzt müssen wir uns mit der Datenbank verbinden, um zu überprüfen ob die Daten richtig eingegeben wurden. Ihr müsst einige Daten zu eurer Datenbank im Folgenden Listing anpassen:

        //Diese Variable wird auf "1" gesetzt, sobald ein Fehler auftreten sollte.
	$err = 0;
	//wurde etwas in das Formular geschrieben?
	if($_POST["nick"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte tragen Sie den Nicknamen ein!");
	}
	if($_POST["pass"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte geben Sie ihr Passwort ein!");
	}
 
	if($err == 0)
	{
		//Ok, verbinde dich mit der Datenbank:
		mysql_connect("localhost", "benutzername", "passwort");
		mysql_select_db("dieDatenbank");
	}

Der neue Code fängt erst ab Linie 17 an. Da wird überprüft, ob kein Fehler aufgerteten ist, also $err null ist. Ist dies der Fall, wird die Verbindung zur Datenbank aufgebaut. Dies geschieht mit den Befehlen mysql_connect und mysql_select_db. Diese befehle müsst ihr noch individuel für euch anpassen.

Jetzt besteht also die Verbindung. Nun suchen wir (im nächsten Listing) einen Eintrag in der Datenbank, mit dem angegebenen Benutzernamen. Wenn einer existiert, wird überprüft, ob das Passwort übereinstimmt. Eine Idee wie wir das machen könnten? Gleich siehst du es. Aber zuerst noch was anderes…

Und zwar will ich noch ein paar Worte zu sicherung der Passwörter verlieren. Ich hoffe, es ist klar, das wir die Passwörter nicht einfach in Klartext abspeichern können. Also so, wie sie eingegeben werden. Zuerst müssen wir die Passwörter verschlüsseln. Ich entfehle, die Passwörter als md5 Hash zu speichern. Mit PHP geht das  mit folgendem Befehl:

md5("ein String");

Da kommt dan irgendwie sowas raus: 0e98c6ac6871898faf1f45f93e1bcf18

Dieses Passwort kann man nun nicht mehr “zurückrechnen”. Allerdings ist es heute durchaus machbar, einen solchen Hash zu “knacken”.

Da wir ja jetzt nicht einfach das eingegebene Passwort mit dem in der Datenbank vergleichen können (sieht ja ganz anderst aus :P ), müssen wir das eingegebene Passwort auch verschlüsseln. Wie das genau funktioniert, seht ihr im nächsten Listing:

	//Diese Variable wird auf "1" gesetzt, sobald ein Fehler auftreten sollte.
	$err = 0;
	//wurde etwas in das Formular geschrieben?
	if($_POST["nick"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte tragen Sie den Nicknamen ein!");
	}
	if($_POST["pass"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte geben Sie ihr Passwort ein!");
	}
 
	if($err == 0)
	{
		//Ok, verbinde dich mit der Datenbank:
		mysql_connect("localhost", "user", "passwort");
		mysql_select_db("db");
 
		//Suche in der Datenbank
		$sql = 'SELECT * FROM `User` WHERE `Nick` LIKE \''.$_POST["nick"].'\' LIMIT 0, 30 ';
		$result = mysql_query($sql);
 
		if (mysql_num_rows($result) == 1) {
			//Es wurde ein Eintrag gefunden. Stimmt das Passwort?
			//Ich nehme an, das Passwort ist in der Datenbank md5 verschlüsselt. Wenn nicht, das md5(...) weglassen.
			$row = mysql_fetch_assoc($result);
			//In $row stehen nun alle Daten des Eintrags.
 
			//Vergleich:
			if($row["Passwort"] == md5($_POST["pass"]))
			{
				//Ok, alle Angaben sind richtig!
			}else{
				echo("Ihr Passwort stimmt nicht...");
			}
 
		}else{
			//Es sollte nur ein Eintrag gefunden werden. Wenn nicht, stimmt was mit den Daten nicht. Existieren entweder garnicht, oder irgendwie doppelt...
			echo("Ihre Daten stimmen nicht. Bitte versuchen Sie es erneut...");
		}
	}

Der neue Code fängt ab Zeile 23 an.

Als erstes speichere ich das MySQL in der Variable $sql ab. Danach schreibe ich das Resultat mit hilfe von mysql_query in die Variable $result.

Mit mysql_num_rows kann man die gefundenen Einträge auslesen. Dies muss in unserem Fall genau eins sein. Denn der Nick ist einzigartig.

Wenn das alles gut ist, werden mit dem Befehl mysql_fetch_assoc alle Felder in das Array $row gespeichert.

Danach wird das Passwort verglichen. Die Sache mit dem md5 ist ja bereits weiter oben beschrieben…

Soooo. Was haben wir jetzt? Ein User kann seine Daten eintragen. Danach wird von uns überprüft, ob das auch alles stimmt. Und was soll nun passieren wenn die Daten stimmen?

Man könnte den user auf die richtige Seite verweisen. Aber dann könnte er auch dahin, wenn er den Link von einem Kollegen, oder so, kennen würde. Also müssen wir den User irgendwie kennzeichnen, und auf jeder Seite prüfen, ob es ihm erlaubt is, diese zu sehen.

Dies geschieht mit einer sogenannten Session. Das ist eine Art Variable, die wir dem User immer mitgeben können, wenn er die Seite wechselt. In genau eine solche Session schreiben wir nun rein, wer er ist, und ob es ihm erlaubt ist, die internen Seiten zu betreten.

Leider ist es auch möglich, eine solche Session zu fälschen. Desshalb müssen wir noch eine kleine Sicherung einbauen. Ich machhe das immer so: Wenn der Login richtig war, generiere ich einen zufälligen 32 Zeichen langen String. Diesen schreibe ich in die Datenbank, und gebe ihn dem User in der Session mit. Jetzt überprüfe ich auf jeder Seite, ob in der Datenbank ein Eintrag mit dem Benutzernamen und diesem String gibt. Wenn ja, ist gut. Ansonsten folgt ein Abbruch, und die Aufforderung, sich erneut einzuloggen.

Um einen Zufallsstring zu generieren, habe ich folgende Funktion:

	function zufallsString($size)
	{
		$result = ""; 
 
		srand((double)microtime()*1000000); 
 
		for($i=0; $i &lt; $size; $i++)
		{
			$num = rand(48,120);
			while (($num &gt;= 58 &amp;&amp; $num &lt;= 64) || ($num &gt;= 91 &amp;&amp; $num &lt;= 96))
			$num = rand(48,120); 
 
			$result .= chr($num);
		}
		return $result;
	}

Diese Funtion schreiben wir am besten ganz an den Anfang des Programmes.

Bis jetzt sieht das ganze wie folgt aus.

	function zufallsString($size)
	{
		$result = ""; 
 
		srand((double)microtime()*1000000); 
 
		for($i=0; $i &lt; $size; $i++)
		{
			$num = rand(48,120);
			while (($num &gt;= 58 &amp;&amp; $num &lt;= 64) || ($num &gt;= 91 &amp;&amp; $num &lt;= 96))
			$num = rand(48,120); 
 
			$result .= chr($num);
		}
		return $result;
	}
 
	//Diese Variable wird auf "1" gesetzt, sobald ein Fehler auftreten sollte.
	$err = 0;
	//wurde etwas in das Formular geschrieben?
	if($_POST["nick"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte tragen Sie den Nicknamen ein!");
	}
	if($_POST["pass"] == NULL)
	{
		//Uups, nick wurde nicht eingetragen, oder existiert gar nicht!
		$err = 1;
		echo("Bitte geben Sie ihr Passwort ein!");
	}
 
	if($err == 0)
	{
		//Ok, verbinde dich mit der Datenbank:
		mysql_connect("localhost", "user", "pass");
		mysql_select_db("usr_web211_2");
 
		//Suche in der Datenbank
		$sql = 'SELECT * FROM `User` WHERE `Nick` LIKE \''.$_POST["nick"].'\' LIMIT 0, 30 ';
		$result = mysql_query($sql);
 
		if (mysql_num_rows($result) == 1) {
			//Es wurde ein Eintrag gefunden. Stimmt das Passwort?
			//Ich nehme an, das Passwort ist in der Datenbank md5 verschlüsselt. Wenn nicht, das md5(...) weglassen.
			$row = mysql_fetch_assoc($result);
			//In $row stehen nun alle Daten des Eintrags.
 
			//Vergleich:
			if($row["Passwort"] == md5($_POST["pass"]))
			{
				//Ok, alle Angaben sind richtig!
				$_SESSION["session"] = zufallsString(32);
				mysql_query('UPDATE `User` SET `Session` = \''.$_SESSION["session"].'\' WHERE `User`.`UserID` = '.$row["UserID"].' LIMIT 1;');
				$_SESSION["UserID"] = $row["UserID"];
 
				echo("
 
<h1>Anmeldung erfolgreich!</h1>
 
 
");
 
			}else{
				echo("Ihr Passwort stimmt nicht...");
			}
 
		}else{
			//Es sollte nur ein Eintrag gefunden werden. Wenn nicht, stimmt was mit den Daten nicht. Existieren entweder garnicht, oder irgendwie doppelt...
			echo("Ihre Daten stimmen nicht. Bitte versuchen Sie es erneut...");
		}
	}

Alles was in eine Sessionvariable, also $_SESSION["irgendwas"], geschrieben wird, ist auch später noch verfügbar (wie wir später noch sehen werden).

Das Loginscript ist soweit fertig. Natürlich kann man anstatt der Meldung, das man sich erfolgreich eingeloggt hat, auch eine Weiterleitung machen.

Jetzt schreiben wir eine Datei, die wir auf jeder internen Seite einbinden werden. In dieser überprüfen wir jedes mal, ob die Session noch aktiv und gültig  ist.

Fortsetzung folgt…
Soll ich weiterschreiben? Dann schreibt mir bitte einen Kommentar. Ich habe nähmlich keine Lust, so viel Zeit zu investieren, wenn niemand meine Arbeit liest ;P

  1. - Du speicherst eine Variabel Session in die DB?!
    - Man sollten einem Button immer ein Namen geben.

    • Ich weise zu erst den String der Session zu, und schreibe danach die Session in die DB. Ich könnte auch direkt den String in die DB schreiben, macht aber keinen unterschied. Oder liege ich da falsch? Ich lasse mich gerne belehren :P

      Button? Stimmt, aber das Formular ist nur zu Testzwecken und nicht Inhalt des Tutorials (siehe “Voraussetzungen”)…

  1. Noch keine TrackBacks.