Wie erstelle ich ein LogIn-Skript?

Das folgende Tutorial nutzt eine Datenbank, in der die Benutzerdaten gespeichert werden und eine Session, in der der Benutzer registriert wird.

Tutorial - Wie erstelle ich ein LogIn-Skript?

Immer wieder taucht die Frage auf, wie man wohl am Besten ein LogIn-Skript schreibt, das einigermaßen sicher ist.

Ich habe mich mal hingesetzt und mir eine Lösung hierfür ausgedacht. Das folgende Tutorial nutzt eine Datenbank, in der die Benutzerdaten gespeichert werden und eine Session, in der der Benutzer registriert wird.
Nur wenn der Benutzer sich über ein Formular mit Benutzernamen und Passwort angemeldet hat, die Daten abgeglichen und korrekt sind, wird der User in der Session registriert.
Gibt ein Benutzer einfach den URL der "sicheren Seite" in die Adresszeile des Browsers ein (er/sie ist nicht in der Session registriert), erfolgt eine Umleitung auf die Anmeldeseite.

Weiterhin ist es Euch nach dem Durcharbeiten dieses Tutorials möglich, einen neuen Benutzer im System anzulegen.

Viel Spaß beim Tutorial wünscht Euch

Andy

Es gibt mit diesem Tutorial eine kleine Änderung im Vergleich zu den bisherigen: Vor den jeweiligen Quelltextzeilen seht Ihr Nummern, die die Quelltextzeilen kennzeichnen. Soll heißen, dass alles hinter einer Nummer auch in eine Zeile in den Quelltexteditor sollte.

Da es mir lieber ist, mehrere Dateien mit weniger Quelltext anzulegen als eine oder zwei Dateien, in denen man vom Quelltext her nicht mehr durchblickt, werden wir in diesem Tutorial insgesamt sechs Dateien anlegen:

  1. connect.inc.php -> Datei mit Verbindungsdaten zum MySQL-Server
  2. index.php -> Die Seite mit dem Formular zum Anmelden
  3. logout.php -> Die Seite, die nach dem Logout angezeigt wird und die die Session zerstört
  4. neu.php -> Die Seite, in der ein neuer Benutzer angelegt wird
  5. sichere_seite.php -> Die Seite, die nach erfolgreichem LogIn angezeigt wird
  6. style.css -> Die Seite, die das Aussehen aller php-Dateien bestimmt

1. Die Tabelle "users" für die Datenbank

Ich gehe in diesem Tutorial davon aus, dass eine Datenbank mit dem Namen login erstellt wurde. Ist dies nicht der Fall, muss die Datei connect.inc.php auf die entsprechende Datenbank angepasst werden.

Um die Benutzerdaten zu speichern brauchen wir natürlich eine entsprechende Tabelle.

Hier zunächst die Angaben, um die Tabelle users zu erstellen:

01  CREATE TABLE 'users' (
02    'id' int(2) unsigned NOT NULL auto_increment,
03    'user' varchar(20) NOT NULL default '',
04    'pass' varchar(50) NOT NULL default '',
05    PRIMARY KEY  ('id')
06  )

Am Besten erledigt Ihr dies mit dem Datenbankverwaltungstool PHPMyAdmin

Einen Benutzer wollen wir uns auch schon einmal anlegen. Hierzu führen wir folgenden MySQL-Befehl aus:

INSERT INTO 'users' SET(user = 'admin', pass = '21232f297a57a5a743894a0e4a801fc3');

Da unsere id ein auto-increment-wert ist, brauchen wir diese nicht anzugeben. Im Feld user der Tabelle users legen wir einen neuen Benutzer namens admin an, das Passwort ist eine Zeichenfolge, die mit der PHP-Funktion md5() erzeugt wird. Das Passwort lautet admin

Wer sein Passwort als md5-Zeichenfolge einmal online sehen will, der geht bitte auf die Seite http://www.mg-umschulung.de/andy/md5.php.
Auf dieser Seite könnt Ihr in ein Textfeld ein Passwort eingeben, das nach einem Klick auf den Button den md5-Hash erzeugt und ausgibt.

2. Die connect.inc.php

Auf diese Datei gehe ich hier nicht näher ein, da sie ebenfalls im Tutorial Gästebuch mit Datenbankanbindung schon ausführlich erklärt wurde. In meinem Fall wurde die Tabelle in der Datenbank login erstellt. Der Quelltext hierzu soll aber gezeigt werden:

01  <?php
02  $dbHost = "localhost";
03  $dbUser = "root";
04  $dbPass = "";
05  $dbName = "login";
06  $connect = @mysql_connect($dbHost, $dbUser, $dbPass) or die("Konnte keine Verbindung zum Datenbankserver aufbauen!");
07  $selectDB = @mysql_select_db($dbName, $connect) or die("Konnte die Datenbank <b>$dbName</b> nicht auswählen!");
08  ?>

Es passiert hier nichts anderes, als dass wir uns mit dem Datenbankserver verbinden und die Datenbank login auswählen.

3. Die Datei index.php

Diese Datei dient uns als Einstiegsseite mit dem Anmeldeformular, das zwei Eingabefelder für den Benutzernamen und das Passwort enthält. Ebenso enthält diese Datei auch Abfragen ob der Benutzername und das Passwort eingegeben wurde und nimmt auch gleich den Datenbankabgleich des Passwortes vor.

Zunächst aber wie gewohnt der Quelltext:

01  <?php
02  session_start();
03  require("connect.inc.php");
04  ?>
05  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
06  <html>
07  <head>
08    <title>LogIn zum Adminbereich</title>
09  <link rel="stylesheet" type="text/css" href="style.css">
10  </head>
11  <body>
12  <?php if(!isset($_POST['submit'])) { ?>
13  <form action="<?php $PHP_SELF ?>" method="post">
14  <table width="400" bgcolor="#000000" border="0" cellpadding="5" cellspacing="1" align="center">
15    <tr>
16      <td bgcolor="#e7e7e7" align="center" colspan="2">
17      <b>Bitte erst anmelden</b>
18      </td>
19    </tr>
20    <tr>
21      <td width="170" bgcolor="#e7e7e7">Benutzername</td>
22      <td width="230" bgcolor="#ffffff"><input type="text" name="username" size="20" class="input"<?php if($_POST['username'] != "" ) {echo ' value="'.$_POST['username'].'"';} ?>></td>
23    </tr>
24    <tr>
25      <td width="170" bgcolor="#e7e7e7">Passwort</td>
26      <td width="230" bgcolor="#ffffff"><input type="password" name="password" size="20" class="input"></td>
27    </tr>
28    <tr>
29      <td bgcolor="#e7e7e7" align="center" colspan="2">
30      <input type="submit" name="submit" value="Anmelden" class="button">
31      </td>
32    </tr>
33  </table>
34  </form>
35  <?php
36  }elseif(!$_POST['username'] || $_POST['username'] == "") {
37    echo '<p align="center">Einen Benutzernamen brauchen wir schon ;-)<br><br><a href="index.php">Zurück</a></p>';
38  }elseif(!$_POST['password'] || $_POST['password'] == "") {
39    echo '<form action="index.php" method="post">';
40    echo '<p align="center">Ein Passwort brauchen wir schon ;-)<br><br>';
41    echo '<input type="hidden" name="username" value="'.$_POST['username'].'">';
42    echo '<input type="submit" name="zurueck" value="Zurück">';
43    echo '</p>';
44    echo '</form>';
45  }else{
46    $password = md5($password);
47    $query = @mysql_query("SELECT user, pass FROM users WHERE user = '".$_POST['username']."'") or die('Select ist fehlgeschlagen!');
48    $result = @mysql_fetch_array($query) or die('<p align="center">Sorry, aber dieser Benutzername existiert nicht!<br><a href="index.php">Zurück</a></p>');
49    if($password != $result['pass']){
50      echo '<form action="index.php" method="post">';
51      echo '<p align="center">Sorry, aber dieses Passwort ist falsch!<br><br>';
52      echo '<input type="hidden" name="username" value="'.$_POST['username'].'">';
53      echo '<input type="submit" name="zurueck" value="Zurück"></p>';
54      echo '</form>';
55      die;
56    }else{
57      $user = $result['user'];
58      session_register('user');
59      echo '<p align="center">LogIn erfolgreich! :-)<br><br><a href="sichere_seite.php">Weiter</a></p>';
60    }
61  }
62  ?>
63  </body>
64  </html>

Zeile 01 - 04

Gleich zu Beginn geht es mit einer PHP-Funktion namens session_start() los. Man sollte eine Session immer vor der ersten HTML-Ausgabe starten. Daher habe ich mir angewöhnt, die Funktion immer an die erste Stelle im Quelltext zu setzen.
Diese Funktion startet nun eine Session und legt auf dem Webserver im temporären Verzeichnis eine Textdatei mit noch leerem Inhalt an. Ebenso wird eine Session-ID erzeugt, mit der die Session eindeutig identifiziert werden kann.

Weiter geht es mit dem Einbinden der Datei connect.inc.php mittels der PHP-Funktion require(). Mit dieser Funktion zwingen wir den Webserver, den Inhalt der in Klammern angegebenen Datei, in unser Skript vorzunehmen. Sollte die Datei nicht existieren, wird das Skript abgebrochen.

Die nächsten Angaben sind HTML-Angaben um eine normale HTML-Datei zu erzeugen.

Zeile 09

Mit <link rel="stylesheet" type="text/css" href="style.css"> binden wir unsere Stylesheet-Datei ein, die wir später noch erstellen werden.

Zeile 12 und 13

In Zeile 12 starten wir die Abfrage <?php if(!isset($_POST['submit'])) { ?>, die auf Deutsch soviel heißt wie: Wenn der Button mit dem name-Attribut submit noch nicht gedrückt wurde, führe folgenden Quelltext aus.

Der folgende Quelltext ist eine ganz normale HTML-Tabelle mit einem Formular, das zwei Textfelder für den Benutzernamen und das Passwort enthält.

Zeile 22

Wer will, der kann das Textfeld Benutzername auch mit einem Wert vorbelegen, wenn der Button gedrückt wurde und das Textfeld Benutzername nicht leer ist.
Dies geschieht mit der Abfrage <?php if($_POST['username'] != "" ) {echo ' value="'.$_POST['username'].'"';} ?> die soviel heißt wie:
Wenn das Feld username über das Formular gepostet wurde und nicht leer ist, belege das Textfeld mit diesem Wert vor.

In Zeile 36 schließen wir die Abfrage aus Zeile 12 wieder und fahren mit weiteren Abfragen fort.

Zeile 36 und 37

Hier erfolgt mit elseif (ansonsten wenn) eine weitere Abfrage. }elseif(!isset($_POST['username']) || $_POST['username'] == "") { Die Abfrage lautet auf Deutsch:
Wenn die Variable username noch nicht gesetzt ist (über ein Formular gepostet -> $_POST) oder (||) die gepostete Variable username leer ist (""), also nichts eingegeben wurde, dann führe nachfolgenden Code aus. Sollte also die Variable username nicht existieren oder keinen Wert aufweisen, dann wird der Code der Zeile 37 ausgeführt, der wie folgt lautet:
echo '<p align="center">Einen Benutzernamen brauchen wir schon ;-)<br><br><a href="index.php">Zurück</a></p>'; Wir geben mit dem echo-Befehl den String, der zwischen den einfachen Anführungszeichen steht, aus. Dieser String beinhaltet einen Link zurück auf die Anmeldeseite.

Zeile 38 - 44

Hier geschieht das Selbe wie in den Zeilen 36 und 37, nur dass dieses mal die Überprüfung für das Passwort stattfindet. Weiterhin geben wir hier mit dem echo-Befehl ein kleines Formular mit einem versteckten Feld (<input type="hidden" name="username" value="'.$_POST['username'].'">), das den geposteten Usernamen als Wert enthält, aus.
Das Feld bekommen wir im Browser nicht zu sehen. Es wird nur im Quelltext der HTML-Seite sichtbar. Weiterhin generieren wir eine Schaltfläche mit der Beschriftung Zurück. Denn wir wollen ja das Textfeld für den Benutzernamen mit einem Wert vorbelegen, wenn dieser bereits gesendet wurde.

Zeile 45 - 48

Wurden beide Angaben (Benutzername und Passwort) eingegeben und über den Button gesendet, gelangen wir in den else-Zweig (Ansonsten). Hier wird als nächstes der Variablen $password mit der PHP-Funktion md5() eine codierte Zeichenkette zugewiesen. Als nächstes erfolgt mit @mysql_query eine Abfrage an die Datenbank, die als WHERE-Klausel die Bedingung stellt, dass nur der Username und das Passwort des Benutzers ausgewählt wird, der mit dem Formular gesendet wurde: WHERE user = '".$_POST['username']."' Mit or die("Select ist fehlgeschlagen!"); generieren wir im Falle eines Fehlschlagens der Abfrage unsere eigene Fehlermeldung die ausgegeben wird und brechen das Skript ab.

In Zeile 48 erzeugen wir eine Variable namens $result, die das Ergebnis unserer Abfrage enthalten soll. Schlägt die Abfrage fehl (Der Benutzername existiert nicht), bekommen wir kein Ergebnis zurück und wir brechen wieder mit or die das Skript ab und erzeugen unsere eigene Fehlermeldung.

Zeile 49 - 55

Haben wir bis hierher alles überstanden (Benutzername und Passwort eingegeben und Benutzer existiert in der Datenbank), starten wir die nächste Abfrage.
In der Abfrage if($password != $result['pass']){ fragen wir, ob das Passwort aus dem Formular ungleich (!=) dem Passwort aus der Datenbank ($result['pass']) ist und wenn ja, führen wir den Code zwischen den geschweiften Klammern aus. Dieser Code ist nichts anderes als wieder ein kleines Formular mit einem hidden-Feld, das den Benutzernamen aus dem Formular als Wert enthält und eine Fehlermeldung, dass das Passwort falsch ist. Ein Zurück-Button rundet die Sache ab und wir gelangen durch Klick auf den Button wieder zum Anmeldeformular mit eingetragenem Benutzernamen.
Den Abschluss bildet der die-Befehl, der unser Skript an dieser Stelle abbricht.

Zeile 56 - 62

Ist auch das eingegebene Passwort korrekt, gelangen wir in den else-Zweig (ansonsten). Wir erzeugen in Zeile 57 die Variable $user und weisen ihr als Wert den über das Formular gesendeten Benutzernamen zu. In Zeile 58 wird nun mit der PHP-Funktion session_register() die Variable $user in der Session registriert. Bitte beachten!
Bei der Funktion session_register() wird das Dollar-Zeichen der Variable weggelassen! Wir schreiben deshalb also session_register('user'). In Zeile 59 geben wir noch eine Erfolgsmeldung aus, dass der LogIn erfolgreich war und generieren einen Link zu der "sicheren" Seite. Als Abschluss müssen wir noch unsere beiden else-Zweige mit schließenden, geschweiften Klammern beenden und in Zeile 62 beenden wir mit ?> unser PHP-Skript

Zeile 63 und 64

Diese beiden Zeilen schliessen das <body>- und das <html>-Tag

Die index.php ist somit abgeschlossen und fertig.

4. Die Datei sichere_seite.php

Unsere nächste Datei soll die "sichere Seite" darstellen, die nach erfolgreichem LogIn und Klick auf den Link in der index.php erscheint.

In dieser Datei passiert nicht viel. Es erscheint eine kleine Brgrüßungsmeldung, ein Link zur Seite neu.php wird generiert und es wird ein Link generiert, der zur Datei logout.php führt. Trotzdem enthält diese Datei eine wichtige Abfrage über die Session.

Aber zunächst wieder der Quelltext:

01  <?php
02  session_start();
03  if(!session_is_registered('user') || $_SESSION['user'] == "") {
04    header("location:index.php");
05    die;
06  }
07  ?>
08  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
09  <html>
10  <head>
11    <title>Sichere Seite</title>
12  <link rel="stylesheet" type="text/css" href="style.css">
13  </head>
14  <body>
15  <table width="400" bgcolor="#000000" border="0" cellpadding="5" cellspacing="1" align="center">
16    <tr>
17      <td bgcolor="#e7e7e7" align="center">
18      <?php echo "<b>Hallo ".$_SESSION['user']."</b>"; ?>
19      <br><br>
20      <b>Hier ist der sichere Inhalt!</b>
21      <br><br>
22      <a href="neu.php">Neuen Benutzer anlegen</a>
23      <br><br>
24      <a href="logout.php">LogOut</a>
25      </td>
26    </tr>
27  </table>
28  </body>
29  </html>

Gleich zu Beginn starten wir wieder ein PHP-Skript mit <?php und in Zeile 2 mit session_start() unsere Session.

Zeile 3 - 7

Um zu verhindern, dass jemand direkten Zugriff auf die Seite durch Eingabe des URL im Browser bekommt, starten wir als erstes eine Abfrage: if(!session_is_registered('user') || $_SESSION['user'] == "") { Die Abfrage lautet auf Deutsch: Wenn die Sessionvariable user noch nicht (!) in der Session registriert ist, oder (||) wenn die Sessionvariable user leer ist ($_SESSION['user'] == ""), dann führe den Code zwischen den geschweiften Klammern aus.

Ist eine der beiden Bedingungen wahr, erfolgt eine Umleitung auf die Datei index.php mit der PHP-Funktion header() und das Skript wird mit dem die-Befehl abgebrochen. Mit location:index.php geben wir die Seite an, auf die weitergeleitet werden soll. Hat also ein User einfach in die Adresszeile des Browser ...../sichere_seite.php eingegeben, so landet er prompt auf der index.php mit dem Anmeldeformular weil in der Sessiondatei auf dem Webserver noch kein user registriert ist.

Zeile 8 - 17

Hier folgen ganz normale HTML-Anweisungen zum Start der HTML-Seite und einer Tabelle.

Zeile 18

Hier starten wir wieder ein kleines PHP-Skript, das eine Begrüßung des angemeldeten Benutzers ausgibt. Mit Hilfe des Zugriffes auf die Session-Datei mittels $_SESSION geben wir die Sessionvariable user aus.

Zeile 19 - 29

Wir geben mit einfachen HTML-Anweisungen einen Text aus und generieren zwei Links. Einen davon auf die Seite neu.php und den anderen auf die Seite logout.php

Die Datei sichere_seite.php wäre hiermit abgeschlossen. Weiter geht es mit der Datei logout.php.

5. Die Datei logout.php

Diese Datei ist dafür zuständig, die Sessiondatei auf dem Webserver zu löschen und, falls dieses schief gehen sollte, eine Meldung auszugeben.

Der Quelltext hierfür:

01  <?php session_start(); ?>
02  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
03  <html>
04  <head>
05    <title>LogOut</title>
06  <link rel="stylesheet" type="text/css" href="style.css">
07  </head>
08  <body>
09  <?php
10  $user = $_SESSION['user'];
11  if(session_destroy()) {
12    echo '<p align="center">Bye bye '.$user.'<br><br>Du hast Dich erfolgreich abgemeldet.<br><br><a href="index.php">Zur Anmeldung</a></p>';
13  }else{
14    echo '<p align="center">Beim Abmelden trat leider ein Fehler auf!<br><br>Bitte schliesse Dein Browserfenster.';
15  }
16  ?>
17  </body>
18  </html>

Zeile 1

Wie immer starten wir in der ersten Zeile unsere Session mit session_start().

Zeile 02 - 09

Hier stehen wieder die Definitionen für den Beginn einer HTML-Seite.

Zeile 10 - 16

Wir weisen in Zeile 10 der Variablen $user den Wert der Sessionvariablen user zu. Danach erfolgt eine Abfrage, die normalerweise nicht nötig sein sollte, aber wir wollen sicher gehen: if(session_destroy()) { Diese Abfrage lautet auf gut Deutsch: Wenn die Session zerstört, gelöscht wurde, dann führe den Code zwischen den geschweiften Klammern aus. Innerhalb der geschweiften Klammern erzeugen wir eine Ausgabe mit dem echo-Befehl, in dem wir die Variable $user benutzen um uns namentlich vom jeweiligen Benutzer zu verabschieden.

In Zeile 13 beginnen wir den else-Zweig. Sollte also wider erwarten etwas bei der Löschung der Session-Datei schief gelaufen sein, so geben wir in Zeile 14 eine Meldung aus, in der wir den Benutzer darum bitten, sein Browserfenster zu schließen. Die Session sollte beim Schließen des Browserfensters endgültig zerstört werden. In Zeile 15 schließen wir unseren else-Zweig und in Zeile 16 beenden wir unser kleines PHP-Skript.

Die Zeilen 17 und 18 dürften inzwischen hinreichend bekannt sein ;-)

Die Datei logout.php ist nun ebenfalls abgeschlossen.

6. Die Datei neu.php

Ich hoffe, Ihr habt noch Lust und den Kopf dazu, wieder einmal jede Menge if-Abfragen zu erstellen und somit einige Daten, die über ein Formular gesendet werden, zu überprüfen ;-).

Na denn Let´s GO

Mittels der Datei neu.php wird ein neuer Benutzer im System angemeldet. Das Anlegen erfolgt über ein Formular, in das der Benutzername und zweimal das Passwort eingegeben werden müssen. Nur wenn der Benutzername nicht schon in der Datenbank existiert und wenn die zwei Passwörter übereinstimmen, erfolgt das Anlegen des neuen Benutzers.

Der Quelltext:

01  <?php
02  session_start();
03  if(!session_is_registered('user') || $_SESSION['user'] == "") {
04    header("location:index.php");
05    die;
06  }
07  require("connect.inc.php");
08  ?>
09  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
10  <html>
11  <head>
12    <title>Neuen Benutzer anlegen</title>
13  <link rel="stylesheet" type="text/css" href="style.css">
14  </head>
15  <body>
16  <?php if(!isset($_POST['submit'])) { ?>
17  <form action="<?php $PHP_SELF ?>" method="post">
18  <table width="400" bgcolor="#000000" border="0" cellpadding="5" cellspacing="1" align="center">
19    <tr>
20      <td bgcolor="#e7e7e7" align="center" colspan="2">
21      <b>Neuen Benutzer anlegen</b>
22      </td>
23    </tr>
24    <tr>
25      <td width="170" bgcolor="#e7e7e7">Benutzername</td>
26      <td width="230" bgcolor="#ffffff"><input type="text" name="username" class="input"<?php if($_POST['username'] != "") { echo ' value="'.$_POST['username'].'"'; } ?> size="20"></td>
27    </tr>
28    <tr>
29      <td width="170" bgcolor="#e7e7e7">Passwort</td>
30      <td width="230" bgcolor="#ffffff"><input type="password" name="password" size="20" class="input"></td>
31    </tr>
32    <tr>
33      <td width="170" bgcolor="#e7e7e7">Passwort wiederholen</td>
34      <td width="230" bgcolor="#ffffff"><input type="password" name="password2" size="20" class="input"></td>
35    </tr>
36    <tr>
37      <td bgcolor="#e7e7e7" align="center" colspan="2">
38      <input type="submit" name="submit" value="Benutzer anlegen" class="button">
39      </td>
40    </tr>
41    <tr>
42      <td bgcolor="#e7e7e7" align="center" colspan="2">
43      <a href="sichere_seite.php">Zurück zur Admin-Seite</a>
44      </td>
45    </tr>
46  </table>
47  </form>
48  <?php
49  }elseif(!isset($_POST['username']) || $_POST['username'] == ""){
50    echo '<p align="center">Einen Benutzernamen brauchen wir schon ;-)<br><br><a href="neu.php">Zurück</a></p>';
51  }elseif(!isset($_POST['password']) || $_POST['password'] == "") {
52    echo '<p align="center">Ein Passwort brauchen wir schon ;-)<br><br><a href="neu.php">Zurück</a></p>';
53  }elseif($_POST['password'] != $_POST['password2']) {
54    echo '<form action="neu.php" method="post">';
55    echo '<p align="center">Die Passwörter stimmen nicht überein!<br><br>';
56    echo '<input type="hidden" name="username" value="'.$_POST['username'].'">';
57    echo '<input type="submit" name="zurueck" value="Zurück"></p>';
58    echo '</form>';
59  }else{
60    $query = @mysql_query("SELECT user FROM users WHERE user = '".$_POST['username']."'");
61    $result = @mysql_fetch_array($query);
62    if($_POST['username'] == $result['user']) {
63      echo '<p align="center">Sorry, dieser Benutzername ist leider schon vergeben!<br><br><a href="neu.php">Zurück</a></p>';
64      die;
65    }else{
66      $username = $_POST['username'];
67      $pass = md5($_POST['password']);
68      if($insert = @mysql_query("INSERT INTO USERS SET user = '$username', pass = '$pass'")) {
69        echo '<p align="center">Der neue Benutzer wurde erfolgreich angelegt!<br><br><a href="sichere_seite.php">Zur Admin-Seite</a></p>';
70      }else{
71        echo '<p align="center">Beim Anlegen des neuen Benutzers trat leider ein Fehler auf!<br><br><a href="neu.php">Zurück</a></p>';
72      }
73    }
74  }
75  ?>
76  </body>
77  </html>

Zeilen 01 - 08

Wir starten wieder wie gewohnt unsere Session und generieren unsere Abfrage, ob die Sessionvariable user nicht leer ist. Dies wurde weiter oben in der Datei sichere_seite.php ja schon erklärt. Ebenso binden wir unsere Verbindungsdatei connect.inc.php wieder mit require() ein.

Zeilen 09 - 47

Dieser Teil des Quelltextes wurde ebenfalls bereits bei der Datei index.php erklärt. Die einzigen zwei Unterschiede bestehen darin, dass wir dieses mal ein zweites Feld für die Passwortwiederholung haben und einen Link zurück auf die index.php generieren. Es ist darauf zu achten, dass das name-Attribut der beiden Passwortfelder nicht gleich sein darf. In meinem Fall heißen sie password und password2.

Zeile 49 und 50

So langsam aber sicher geht es ans Eingemachte ;-) Wir generieren eine Abfrage, }elseif(!isset($_POST['username']) || $_POST['username'] == ""){ die auf Deutsch soviel heißt wie: Wenn die Variable username nicht gesetzt ist, oder die Variable username leer ist, dann führe den Code in den geschweiften Klammern aus. Wurde also kein Benutzername im Formular eingegeben, geben wir per echo-Befehl eine Meldung und einen Link zurück zur neu.php aus.

Zeile 51 und 52

In diesen beiden Zeilen passiert das Gleiche wie schon beim Benutzernamen. Es wird geprüft, ob das erste Passwort eingegeben wurde. Wenn nicht, erfolgt wieder einmal eine Meldung und ein Link zurück zur neu.php wird wieder generiert.

Zeile 53 - 58

Sind die Daten (Benutzername und das erste Passwort) eingegeben worden, so prüfen wir in Zeile 53 nach, ob das erste Passwort nicht mit dem zweiten Passwort übereinstimmt. Ist dies der Fall (verschiedene Eingaben), so wird wieder einmal eine Fehlermeldung ausgegeben und wir generieren uns mal wieder ein kleines Formular mit einem hidden-Feld, das als Wert den geposteten Benutzernamen enthält. Ein Button mit der Aufschrift Zurück rundet die Sache ab und wir landen wieder bei der Eingabemaske. Dieses mal aber mit bereits vorbelegtem Benutzernamen.

Zeile 59 - 64

Nach bestandener Prüfung aller vorhergehenden Prüfungen (Benutzernamen eingegeben, Passwörter sind identisch) gelangen wir in den else-Zweig der wiederum ein paar Abfragen bereit hält. In Zeile 60 wird eine Abfrage an die Datenbank gesendet, die einen Benutzer auswählen soll, der den gleichen Benutzernamen hat, wie der, der über das Formular gesendet wurde.

In Zeile 61 erzeugen wir eine Variable namens $result, die das Ergebnis dieser Abfrage als Wert bekommen soll.
In der Abfrage in Zeile 62 vergleichen wir ob der Benutzername aus dem Formular gleich dem Benutzernamen aus der Datenbankabfrage ist. if($_POST['username'] == $result['user']) {.
Ist dies der Fall, wird - wie sollte es anders sein - eine Fehlermeldung ausgegeben, in der wir darauf hinweisen, dass ein Benutzer mit diesem Namen bereits existiert. Ebenso wird ein Link zurück auf die neu.php generiert und wir brechen das Skript mit die ab.

Zeile 65 - 67

Existiert noch kein Benutzer mit dem über das Formular eingegebenen Benutzernamen, so gelangen wir abermals in einen else-Zweig in dem wir als erstes eine Variable namens $username erzeugen und dieser als Wert den im Formular angegebenen Benutzernamen zuweisen. Als nächstes erzeugen wir nochmal eine Variable namens $pass, der wir als Wert den md5-Hash des geposteten Passwortes mit Hilfe der Funktion md5() zuweisen.

Zeile 68 und 69

Wieder einmal erfolgt ein if-Abfrage. Wir erzeugen die Variable $insert die als Wert die Rückgabe aus der folgenden Datenbankabfrage erhält. In diesem Fall true oder false. if($insert = @mysql_query("INSERT INTO USERS SET(user = '$username', pass = '$pass')")) { Mit INSERT INTO users sagen wir dem Datenbankserver, dass wir einen Datensatz in die Tabelle users eintragen wollen. Mit VALUES('','$username','$pass') legen wir die Werte der Reihe nach fest wie sie in der Tabelle stehen. Den ersten Wert können wir leer lassen, da unsere id ein auto-increment-wert ist und dadurch automatisch hochgezählt wird. Gibt uns nun die Funktion @mysql_query ein positives Ergebnis zurück (true), so geben wir eine Erfolgsmeldung aus und generieren einen Link zurück auf die sichere Seite.

Zeile 70 und 71

Wurde von der Funktion @mysql_query ein negatives Ergebnis (false) zurückgegeben, gelangen wir in den nächsten else-Zweig, in dem wir auf einen Fehler beim Eintragen in die Datenbank hinweisen und generieren einen Link zurück auf die neu.php.

Zeile 72 - 74

Natürlich dürfen wir nicht vergessen, unsere ganzen else-Zweige mit schlißenden geschweiften Klammern zu schließen.

Ich hoffe, diese Tortur an if-Abfragen und if-Abfragen innerhalb von else-Zweigen habe ich einigermaßen verständlich rübergebracht und es treten keine - oder zumindest wenige - Probleme damit auf. Unsere Datei neu.php wäre hiermit abgeschlossen.

Was uns jetzt noch fehlt, ist unsere CSS-Datei, die das Aussehen der PHP-Seiten steuert. Es wird jetzt genügend Leute geben, die schreien "das würde ich doch als erstes machen!", aber ich halte mich anfangs nicht so sehr mit Design-Dingen auf. Denn ich habe es entweder schon auf Papier oder im Kopf, wie die Seiten auzusehen haben ;-) Und außerdem geht es in dem Tutorial ja hauptsächlich um PHP und MySQL.

7. Die Datei style.css

Um nicht auf jeder einzelnen Seite mit Angaben wie z.B. <font-family="Verdana, Arial, Helvetica, sans-serif"> usw schreiben müssen, legen wir uns eine zentrale Stylesheet-Datei an, die das Aussehen des Textes, der Links, der input-Felder usw. vornimmt. Dies hat den großen Vorteil, dass wir nicht bei jeder Änderung des Designs der Seiten alle Seiten nach unseren FONT-Tags durchsuchen und diese ändern müssen. Wir ändern stattdessen nur die eine Stylesheet-Datei.

Hier der Quelltext für die Stylesheet-Datei:

01  body, td {
02    font-family: Verdana, Arial, Helvetica, sans-serif;
03    font-size: 9pt;
04    color: #000000;
05  }
06  a:link {
07    font-family: Verdana, Arial, Helvetica, sans-serif;
08    font-size: 9pt;
09    color: #000099;
10    text-decoration: none;
11  }
12  a:visited {
13    font-family: Verdana, Arial, Helvetica, sans-serif;
14    font-size: 9pt;
15    color: #000099;
16    text-decoration: none;
17  }
18  a:hover {
19    font-family: Verdana, Arial, Helvetica, sans-serif;
20    font-size: 9pt;
21    color: #0000ff;
22    text-decoration: underline overline;
23  }
24  a:active {
25    font-family: Verdana, Arial, Helvetica, sans-serif;
26    font-size: 9pt;
27    color: #000099;
28    text-decoration: none;
29  }
30  .input {
31    width: 150px;
32    background-color: #e7e7e7;
33    border: 1px solid #000000;
34    font-family: Verdana, Arial, Helvetica, sans-serif;
35    font-size: 9pt;
36    color: #000000;
37  }
38  .button {
39    background-color: #e7e7e7;
40    border: 1px solid #000000;
41    font-family: Verdana, Arial, Helvetica, sans-serif;
42    font-size: 9pt;
43    color: #000000;
44  }

Zu beachten ist, dass CSS-Definitionen nicht wie in HTML in spitze Klammern geschrieben werden und die Wertzuweisung nicht durch ein Gleichheitszeichen erfolgt, sondern, dass wir zunächst das/die HTML-Tag/s, die wir definieren wollen, angeben. Zwischen die geschweiften Klammern werden dann zunächst die jeweiligen Eigenschaften wie z.B. font-family geschrieben. Es folgt der Doppelpunkt hinter dem die jeweilige Wertzuweisung erfolgt. Werden mehrere Eigenschaften definiert, so sind diese durch einen Strichpunkt zu trennen wobei dies bei der letzten Definition nicht unbedingt nötig ist.

Zeile 01 - 05

Hier definieren wir die zwei HTML-Tags body und td (Tabellenzellen) neu, indem wir als Schriftfamilie die Schriften Verdana, Arial, Helvetica, sans-serif bestimmen. Auf Windows-Systemen wird die Schrift Verdana angezeigt, auf einem MAC ist diese Schrift aber nicht unbedingt verfügbar. Also greift sich der MAC die Schriftart Helvetica. Sind die drei ersten Schriften nicht auf dem jeweiligen Computersystem vorhanden, so wird mit der Angabe sans-serif eine Serifenlose Ersatzschriftart gewählt. Mit font-size: 9pt; legen wir die Schriftgröße fest Die Eigenschaft color bestimmt die Schriftfarbe. In unserem Fall (#000000) schwarz. Die Angabe erfolgt hier als RGB-Wert. Möglich waäre auch die Definition -> color: black;

Zeile 06 - 29

In diesem Abschnitt definieren wir das HTML-Tag A href neu. Für Links gibt es bekanntlich vier verschiedene Zustände:

  1. Der Link selbst a:link
  2. Der besuchte Link a:visited
  3. Der Roll-Over-Effekt a:hover
  4. Der aktive Link a:active

Deshalb wird das A-Tag auch viermal definiert.

Als erstes wird der normale Link neu definiert, indem wir ihm wie schon bei den body und td-Tags die Schriftfamilie, die Schriftgröße und die Schriftfarbe zuweisen. Damit sich die Links vom übrigen Text etwas abheben, weisen wir den Links eine andere Farbe zu. Mit der Eigenschaft text-decoration können wir bestimmen, ob der Link beispielsweise unterstrichen (underline), keine Eigenschaft (none) haben soll, oder unterstrichen UND überstrichen (underline overline) werden soll. Ich habe mich hier entschieden, für den normalen Link keine Eigenschaft anzugeben.

Die nachfolgenden Definitionen für visited, hover und active unterscheiden sich kaum. Nur dass ich beim roll-over-Effekt (hover) eine andere Farbe angebe und als text-decoration underline overline gewählt habe.

Ein kleiner Testlink

Zeile 30 - 37

Hier definieren wir eine Klasse, die mit einem Punkt (.) beginnt. Der Name hinter dem Punkt ist Euch überlassen. Ich habe hier input gewählt, weil ich mit den Definitionen die Textfelder der Eingabemasken formatieren möchte. Mit der Eigenschaft width können wir die Breite der Textfelder bestimmen. In diesem Fall 150px (Pixel). Mit der Eigenschaft background-color bestimmen wir die Hintergrundfarbe der Textfelder. Hier der RGB-Wert #e7e7e7. Um den Rahmen um das Textfeld zu gestalten, habe ich die border-Eigenschaft mit drei Werten definiert: 1px -> Ein Rand mit einer Stärke von einem Pixel. solid -> einfacher Rahmen. Wer will, probiert hier auch einmal dashed aus ;-) #000000 -> Rahmenfarbe schwarz.

Die restlichen Zeilen sind schon aus den anderen Definitionen bekannt. Sie betreffen die Schriftformatierung.

Zeile 38 - 44

Hier definieren wir wieder eine Klasse. Dieses mal aber für die Buttons. Die Vorgehensweise ist wieder die Gleiche wie bei der Klasse input. Nur dass wir dieses mal keine Breite brauchen. Ein Button passt sich ja dem value-Attribut an.

Wie Ihr wahrscheinlich bemerkt habt, ist in den HTML-Tags input und input submit der index.php und der neu.php jeweils ein Attribut namens class="" mit angegeben. Mit diesen Attributen wird den Textfeldern und den Buttons eben genau diese CSS-Klassen zugewiesen. Lässt man diese Attribute weg, bleiben ganz normal HTML-Buttons übrig.

Jetzt erst mal tief durchatmen und das neu erstellte LogIn-Skript ausprobieren. Aber nicht verzweifeln wenn es nicht gleich auf Anhieb funktionieren sollte. Sind alle PHP-Befehle mit einem Strichpunkt (;) abgeschlossen? Haben sich keine Tippfehler eingeschlichen? Stimmen die Verbindungsdaten zum MySQL-Server?

Bei Fragen stehe ich wie immer jederzeit per E-Mail zur Verfügung. Getestet wurde dieses Skript mit der PHP-Version 4.1.1 auf der lokalen Festplatte und mit der PHP-Version 4.2.2 online.

Download der Quelldateien

Erfahrungen


Ein Gutes, Neues Jahr 2010 wünsche ich erst einmal allen :-) @ jimbob-walton: Dann mach was.... Wie auf meiner eigenen Seite zu sehen, ist kaum Zeit vorhanden. Aber man kann sich gerne kurzschließen und über gewisse Dinge quatschen ;-)
Geschrieben von Proggi Am 02.01.2010 20:03:50

@Andreas: In PHP bin ich (noch) nicht so fit, könnte aber meine Unterstützung anbieten was Design (css) betrifft (also weg mit den Tabellen :-)). [br /]Weithin könnte ich auch für diejenigen, die mit MySQL noch Schwierigkeiten haben, nen Tutorial (in Bezug auf dieses Projekt) machen, so dass das Ganze durchgängig wäre. Also gib hier kurz Bescheid, falls Du was machen willst (ich mach auf jeden Fall was :-) da ich ein entsprechendes Login-Script benötige.
Geschrieben von jimbob-walton Am 11.12.2009 16:52:27

wir würden uns freuen :)
Geschrieben von admin Am 11.12.2009 15:35:52

Hi Ihrs ;)

Es freut mich einerseits, dass dieses Tutorial immer noch so beliebt ist und auch immer noch durchgearbeitet wird.
Allerdings kann man anhand des Datums sehen, dass dieses Tutorial schon ziemlich alt ist und keineswegs mehr dem heutigen Stand der Dinge entspricht.
Ich selbst, als Autor dieses Tutorials, empfehle jedem, das Tutorial nur als Übung anzusehen und keinesfalls 1:1 online einzusetzen!

Ich denke darüber nach, ob ich evtl. ein neues Tutorial schreiben soll, das den heutigen Ansprüchen genügt und auch die entsprechenden Sicherheitsvorkehrungen beinhaltet........


Netten Gruß :-)
Andreas Zimare - alias Proggi
http://www.kit-spiele.de
Geschrieben von Proggi Am 10.12.2009 00:13:50

Seite 3 ist ein Fehler im Quellcode, deshalb kann ein Einloggen nicht funktionieren (der md5-Hash wird mit der Verschlüsselung von 'nothing' (d41d8cd98f00b204e9800998ecf8427e) zurückgegeben.
Der Fehler liegt in Zeile
46 $password = md5($password);
Es muss heißen:
46 $password = md5($_POST['password']);
Dann klappt alles einwandfrei :-)

Insgesamt sehr lehrreiches Tutorial - insbesondere durch Deine Erläuterungen zum Quellcode. Da hast Du Dir wirklich sehr viel Mühe gegeben.
Danke und mach weiter so!

Viele Grüße
Markus
Geschrieben von jimbob-walton Am 09.12.2009 23:09:48

Hier Kannst Du einen Kommentar verfassen


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

Verwandte Beiträge

Variablen über mehrere Seiten hinweg verwenden - der Session-Befehl macht 's möglich!

Oberste Voraussetzung um Session-Befehle korrekt auszuführen ist, dass der Provider a) PHP und b) das speichern von Sessions auf dem Server überhaupt erlaubt. Wird der Session-Befehl unterstützt jedoch nicht das direkte speichern von Sessions bzw. Sess ...

ndo@

Autor : ndo@
Kategorie: PHP-Tutorials

Templates in PHP

Ein kleines Tutorial zum Einsatz von Templates in PHP am Beispiel der Apolda Templateklasse (kuerbis.org/template/) ...

stulgies@

Autor : stulgies@
Kategorie: PHP-Tutorials

Konfiguration eines Linux-Rechners als DSL-Router

Dieser Artikel beschreibt wie man unter LINUX einen DSL-Rooter für Windows konfiguriert. ...

tschiesser@

Autor : tschiesser@
Kategorie: Linux & Server Tutorials

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