Login/Memberbereich mit Sessions

Adminmodul für das eigene Gästebuch, Controlpanel eines Forum oder einfach nur für ein geschützer Bereich.

Einleitung:

Um was geht?s diesmal ?

Naja um einen Passwort gesicherten Bereich, zB. Ein Adminmodul für das eigene Gästebuch oder das Controlpanel eines Forum oder einfach nur ein geschützer Bereich in einem Forum. Hier wird diesmal nur das Grundgerüst geliefert aber aufgrund dessen, dass es über Sessions gereglt wird sollte es kein Problem sein es zu erweitern.

Was wir brauchen :

Ich gehe hier davon aus dass eine MySQL Datenbank besteht die adminzone heisst und aus einer Tabelle Namens zugriff besteht die vier Spalten ( id, name, pass, level ) hat. Diese muss zuerst einmal angelegt werden, am besten man verwendet dazu phpMyAdmin oder MySQL-Front.

Die Spalten name und pass sollte vom Typ her varchar sein mit einer Länge von 20, id vom Typ int, auto_increment, sie ist der PrimaryKey. Die Spalte level vom Typ tinyint.

Dann muss man noch mindestens einen Datensatz einfügen damit man ich auch einloggen kann ;)

Die Scripte :

Es gibt wieder ein Script var.inc.php in welchem die ganzen Variablen drin enthalten sein sollten die von vielen Scripten gebraucht werden. Dies sind hier die Variablen für den Datenbank zugriff . var.inc.php

<?php
// Datenbank Variablen
$dbserver "localhost"// Datenbankserveradresse
$dbname "adminzone"// Name der Datenbank
$dbuser ""// Username des Datenbankbenutzers 
$dbpass ""// Passwort des Datenbankbenutzers
?>

Sollte alles selbsterklärend sein.

Als weiteres Script brauchen wir die login Seite, auf welcher man Username und Passwort eingeben kann, diese Seite ist reines HTML und sollte deshalb niemandem Probleme bereiten, falls doch verweise ich auf http://www.netzwelt.com/selfhtml/ .

login.html

<html>
<head>
<title>login</title>
</head>
<body>
<form action="verify.php" method="post">
Username : <br>
<input type="text" name="username" size="20" maxlength="20"><br>
Passwort : <br>
<input type="password" name="passwort" size="20" maxlength="20"><br>
<input type="submit" name="absenden" value="einloggen">
</form>
</body>
</html>

Wie man an der action der Form erkennen kann geht es bei verify.php weiter, dort wird jetzt die Session gestartet und die Daten überprüft und als Sessionvariablen gespeichert.
verify.php

<?php
session_start
();
?>

So, hier wird die Session gestartet, es ist wichtig das kein HTML Code davor steht. Es gibt auch behauptungen dass garkein Code davor stehen darf, was allerdings quatsch ist. Vor dem session_start darf nur kein Code stehen der irgendwie im Browser angezeigt wird.

<?php
include('var.inc.php');
?>

Hier werden die ?globalen? Variablen included. Dies macht Sinn bei grösseren Projekten bei denen bestimmte Daten von vielen Scripten benötigt werden, zB. Die Daten zur Konnektierung zur Datenbank, durch das includen hat man den Vorteil dass man die Daten nur einmal verändern muss, anstatt das man jedes Script ändern müsste.

<?php
if ((!isset($username)) OR (!isset($passwort)))
{
die (
"Sorry, aber ohne Name bzw. Passwort geht hier nichts !");
}
?>

Hier wird überprüft ob die Variablen $username und $passwort existieren. Ist dies nicht der Fall dann bricht das Script ab, denn wo nix da ist braucht man auch nix zu überprüfen. Man sollte dies eigentlich mit allen Variablen tun die von einem anderen Script erwartet werden denn es kann zu unangenehmen Fehlern kommen wenn das Script auf Variablen zugreifen will die nicht existieren, das sieht nicht schön aus.

<?php
$conn 
= @mysql_connect($dbserver,$bduser,$dbpass);
if (!
$conn)
{
die (
"Sorry, Verbindungsversuch zur Datenbank ist fehlgeschlagen !");
}
?>

Hier wird eine Verbindung zum MySQL-Server aufgebaut, das @ Zeichen unterdrückt eine Fehlermeldung wenn der Versuch fehlschlägt, dies geschieht wieder aus Schönheitsgründen, naja und dann wird geschaut ob die Verbindung zustande kam. if(!$conn) ist wieder so ein kleiner Kniff, denn eigentlich will man ja wissen ob es geklappt hat, aber es sinnvoller zu schaun ob es nicht geklappt hat, denn dann brechen wir das Script ab und müssen nur einen Befehl in die if-Klammer setzen, ansonsten müssten wir alle weiteren Befehle einklammern. Das ! Zeichen negiert den Ausdruck $conn, falls dieser also FALSE ist dann wird der if Ausdruck TRUE, denn Minus mal Minus ist ja auch Plus.
Es werden hier viele logische Elemente benutzt die es lohnt sich vor Augen zu führen da man sich dadurch eine Menge an Programmierarbeit sparen kann. Ausgenutzt wird das mysql_connect ein FALSE zurück gibt wenn die Verbindung nicht zustandekommt. Da aber der if Befehl überprüft ob der Ausdruck TRUE ist müssen wir ihn negieren , also Fragen wir ?WENN (if) NICHT (!) VERBINDUNG ($conn) DANN TUE DIES (die)?. Es macht öfters sinn sich die Programmzeilen, gerade bei Abfragen, in ?Deutsch? zu übersetzten, dann wird der es manchmal einfachen, besonders bei komplexeren logischen Ausdrücken.

<?php
mysql_select_db
($dbname,$conn);
?>

Hier wird dann die Datenbank ausgewählt, dieser Befehl ist nötig wenn mehrere Datenbanken auf den DB-Server existieren. Damit wird die erstellte Verbindung $conn mit der Datenbank $dbname ?verbunden?. Es kann ja durchaus sein dass man mehrere Verbindungen zu verschiednen Datenbanken aufbaut.

<?php
$query 
"SELECT pass, level FROM zugriff WHERE name = '".$username."'";
$result mysql_query($query,$conn);
?>

Diese beiden Zeilen senden eine SQL Abfrage an die Datenbank. Ich mache das immer so das ich eine Variable $query erzeuge die dann im mysql_query Befehl abgesendet wird, theoretisch kann man auch alles direkt eintragen, das würde dann so aussehen :

<?php
$result 
mysql_query("SELECT pass, level FROM zugriff WHERE name = '$username'",$conn);
?>

Ich finde allerdings das dadurch die Übersicht verloren geht, ausserdem erstrecken sich kompliziertere Abfragen oft über mehrere Zeilen und dann sieht es wirklich nimmer gut aus ! Die SQL Abfrage macht folgendes sie ruft aus der Datenbank zugriff die Werte pass und level ab die in den Datensatz stehen wo die Spalte name mit $username gleich ist. SQL ist eigentlich ein gebrochenes Englisch und man kann sich dies zunutze machen wenn man mal wieder bei einem Query nicht weiterkommt. Ich übersetzte mir den Kram dann ins deutsche, hier wäre es ungefähr so :

?LIES (SELECT) pass und level AUS DER DATENBANK (FROM) zugriff WO (WHERE) name GLEICH (=) ?$username? IST?.

So kann man sich das schön herleiten finde ich.

<?php
$zeileholen 
mysql_fetch_array($result,MYSQL_ASSOC); 
mysql_close($conn);
?>

So, in $zeileholen wird mittels mysql_fetch_array das Ergebnis des Querys eingelesen. MYSQL_ASSOC signalisiert php dass $zeileholen ein assoziatives Array werden soll. Dies ist eigentlich am besten handlebar, da $zeileholen[?pass?] dann den Wert von pass bekommt usw.. Dass ist übersichtlicher wie $zeileholen[1] zB. , denn dann ist ist die Reihenfolge so wie man es im SELECT Statement angibt, ändert man die Reihenfolge oder fügt etwas neues ein kann das Script ganz schön ins schleudern kommen.

Mit mysql_close($conn) wird dann die Verbindung wieder abgebaut. Sie wird nichtmehr gebraucht. Dieser Befehl muss eigentlich nicht angegeben werden weil nach beenden des Scripts sowieso alle Verbindungen gekappt werden. Es ist aber von der Performance her besser, gerade wenn man viele Verbindungen benutzt und dazu noch einen lahmen Server hat.

<?php
if (!$zeileholen)
{
die (
"Sorry, aber dieser Name ist leider nicht bekannt !");
}
?>

So hier haben wir wieder die ?negierte? if Abfrage, denn auch mysql_fetch_array gibt ein FALSE zurück wenn kein Datensatz gefunden wurde. Naja und wenn jemand nicht in der Datenbank steht dann geht?s auch nicht weiter, also die(..).

<?php
if ($zeileholen["pass"] <> $passwort)
{
die (
"Sorry, aber dieses Passwort passt nicht zum Usernamen !");
}
?>

So, hier wird jetzt abgefragt ob das Passwort aus der Datenbank mit dem $passwort übereinstimmt, bzw. es wird wieder abgefragt ob es nicht gleich ist, warum das haben wir weiter oben ja schon besprochen. Hier sieht man auch schön wie übersichtlich es ist wenn da steht $zeileholen[?pass?]. Ich meine, der der das Script geschrieben hat, erkennt auch $zeileholen[1] aber einer der das Script vorher nicht kannte, sieht auf einen Blick was aus der Datenbank kommt, darauf sollte man auch achten, man ist nicht allein auf der Programmiererwelt.

<?$level $zeileholen["level"];
?>

Hier wird jetzt der Wert level, aus der DB, in die Variable $level gespeichert, dies mache ich damit ich es als Sessionvariable registrieren kann.

<?php
session_register
('username');
session_register('level');
?>

So, hier werden jetzt die Variablen $username und $level als Sessionvariablen registriert, sie stehen jetzt in allen weiteren Scripten zur verfügung welche eine Session mit session_start() starten bzw. aufrufen. Hier liegt ein kleine Falle, und zwar ist beim session_register Befehl darauf zu achten dass das $ im Variablenname wegfällt.

<?php
header 
("Location:admin.php");
?>
?>

Und zu guter letzt wird mittels des header Befehls zum Hauptscript admin.php weitergeleitet. Für den header Befehl gibt dasselbe wie für session_start , es darf kein HTML Code davor stehen, gegenseit ?beissen? sie sich nicht und von anderen php Befehlen lassen sie sich auchnicht ?beissen? solange kein HTML Code erzeugt wird, zB. mit echo !

admin.php

<?php
session_start
();
?>

Wieder muss die Session gestartet werden, der Server schaut jetzt nach ob der User schonmal da war.

<html>
<head>
<title>Adminzone</title>
</head>
<body>

Nachdem, die Session gestartet wurde darf auch HTML zum Einsatz kommen.

<?php
if (!session_is_registered('username'))
{
die (
"Sorry, aber sie haben sich wohl nicht eigeloggt, oder ?");
}
?>

Mit session_is_registered kann man überprüfen ob Sessionvariablen gespeichert sind. Ist in etwa dasselbe wie isset für normale Variablen. Wiedermal kommt die ?negierte? if Abfrage zum Einsatz, wenn es keine gespeicherte Sessionvariable gibt dann hat man sich ja auchnicht eingeloggt, also hat man auch keine Rechte. Ansonsten ....

<?php
echo "Hi ".$username." !";
echo 
"<br> Dein Userlevel ist ".$level;
?>

... wird man herein gebeten. Der Userlevel hat hier eigentlich keine Verwendung, er ist eigentlich nur als beispiel eingebaut, zB. um bestimmte Funktionen zur Verfügung zu stellen. Mit Level 1 wird dies ausgegeben, mit Level 2 das usw.

<?php
?>
<br>
<input type="button" name="logout" value="logout" onClick="location.href='logout.php'">
</body>
</html>

Nun noch ein Button, weil ausloggen sollte man sich aus Sicherheitsgründen schon ! Nun kommt noch das Auslogscript und wir sind durch
logout.php

<?php
session_start
();
Session da ?
session_destroy();
?>

Dann müssen wir sie löschen ;)

<?php
header
("Location:login.html");
?>

Und dann gehen wir wieder weiter zum login-Screen zurück und unsere Rundreise ist beendet. Diese Scripts haben jetzt noch keinen richtigen Nutzen, allerdings muss man eigentlich nur die admin.php erweitern und über die $level Variable kann man schon jede Menge Individualität einbauen. Ich hoffe das Tutorial ist zu gebrauchen, gerne nehme ich Verbesserungen und comments entgegen.

Mit freundlichen Grüßen
Joel

Erfahrungen


Hallo kann mir jemand helfen?

ich habe alles so schritt für schritt gemacht wie in diesem Tutorial, bekomme aber folgende Fehlermeldung:
[code]Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00b0fd4/phpscripts/verify.php:4) in /www/htdocs/w00b0fd4/phpscripts/verify.php on line 54[/code]
Geschrieben von MeinInternet Am 27.10.2009 14:40:06

Hier Kannst Du einen Kommentar verfassen


Bitte gib mindestens 10 Zeichen ein.
Wird geladen... Bitte warte.
* Pflichtangabe

Verwandte Beiträge

Wird geladen... Bitte warte.
Wird geladen... Bitte warte.

Tutorial veröffentlichen

Tutorial veröffentlichen

Teile Dein Wissen mit anderen Entwicklern weltweit

Du bist Profi in deinem Bereich und möchtest dein Wissen teilen, dann melde dich jetzt an und teile es mit unserer PHP-Community

mehr erfahren

Tutorial veröffentlichen