Webseitenschutz mit PHP und MySQL (Tutorial)

[Bildschirmfoto] Webseitenschutz mit PHP und MySQL

Die folgenden Code-Beispiele zeigen Ihnen, wie Sie PHP, MySQL und Sessions verwenden um einen sicheren Login-Bereich für Ihre Website zu bauen.

Eine neue Datenbank-Tabelle erstellen

Mit phpMyAdmin - phpMyAdmin.net oder dem Adminer - adminer.org eine neue Datenbank-Tabelle erstellen.

Die Tabellenstruktur enthält neben der ID (id) den Namen des Benutzers (name) seine E-Mail Adresse (email) das Passwort (password) und den Status (status). Danach folgen das Datum der Registrierung (created_at) und das Datum der letzten Anmeldung (updated_at).

[Bildschirmfoto] Eine neue Datenbank-Tabelle mit dem Programm: 'Adminer' erstellen.
Eine neue Datenbank-Tabelle mit dem Programm: 'Adminer' erstellen.

Wer sich die Arbeit mit dem eintragen sparen möchte, kann das folgende SQL-Kommando im Programm: Adminer oder in phpMyAdmin ausführen.

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(75) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(75) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `status` tinyint(1) NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
[Bildschirmfoto] Das SQL-Kommando mit dem Programm: 'Adminer' ausführen.
Das SQL-Kommando mit dem Programm: 'Adminer' ausführen.

Die Verbindung zur Datenbank

Um auf eine Datenbank zugreifen zu können, müssen Sie zuerst eine Verbindung zum Datenbank-Server herstellen und eine bereits vorhandene Datenbank auswählen. Die vier Zugangsdaten zur Datenbank bekommen Sie von Ihrem Webspace-Provider. Bei den Zugangsdaten handelt es sich um die Host-Adresse dort ist die Datenbank gehostet, den Datenbanknamen, den Benutzernamen und das Passwort dieses können Sie meist selbst festlegen.

Hier im Beispiel wurde die Host-Adresse localhost, als Datenbank test gewählt mit dem Benutzernamen root und einem leeren Passwort. In der Datei ist noch definiert das PHP-Fehlermeldungen und MySQL-Fehlermeldungen ausgegeben werden sollen.

Außerdem eine PHP-Variable ($FREISCHALTUNG), die bestimmt ob der registrierte Benutzer sich direkt nach der Registrierung anmelden kann oder dies durch den Administrator geschehen soll.

Quelltext:  connect.php AusblendenKopierenLinkZeilen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
/*
 * Verbindung - connect.php
 */

// PHP Fehlermeldungen anzeigen
error_reporting(E_ALL);
ini_set("display_errors"true);

// Zugangsdaten zur Datenbank
$DB_HOST "localhost"// Host-Adresse
$DB_NAME "test"// Datenbankname
$DB_BENUTZER "root"// Benutzername
$DB_PASSWOR""// Passwort

// Den Benutzer automatisch nach der Registrierung freischalten? 0 / 1
$FREISCHALTUNG 1// 1 = ja

/* Zeichenkodierung UTF-8 bei der Verbindung setzen,
Und eine PDOException bei einem Fehler auslösen. */
$OPTION = [
    
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
    
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
];

try {
    
// Verbindung zur Datenbank aufbauen
    
$db = new PDO("mysql:host=" $DB_HOST ";dbname=" $DB_NAME,
        
$DB_BENUTZER$DB_PASSWORT$OPTION);
} catch (
PDOException $e) {
    
// Bei einer fehlerhaften Verbindung eine Nachricht ausgeben
    
exit('Verbindung fehlgeschlagen! ' $e->getMessage());
}

Die Registrierung des Benutzers

Die Registrierung des Benutzers erfolgt in der Datei: register.php. In einem Formular muss der Name des Benutzers, seine E-Mail Adresse und das Passwort eingegeben werden. Nach der Übergabe der Benutzerdaten wird überprüft ob der Name oder die E-Mail Adresse bereits vorhanden sind. Ist dies dann negativ, werden die Daten eingetragen, das Passwort wird dabei verschlüsselt hinterlegt.

Quelltext:  register.php AusblendenKopierenLinkZeilen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<?php
/*
 * Registrierung - register.php
 */

// Verbindung zur Datenbank
include "connect.php";

$ausgabe "";

// Variablen setzen
$name $_POST["name"] ?? ''// Text-Eingabefeld
$passwort $_POST["passwort"] ?? ''// Passwort-Eingabefelder
$passwortB $_POST["passwortB"] ?? '';
$email $_POST["email"] ?? ''// E-Mail-Eingabefeld

// Fehlerausgaben setzen
$fehler = ["name" => "",
    
"email" => "",
    
"passwort" => "",
];

// Wurden Daten über POST gesendet
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    
// Name und E-Mail überprüfen ob diese bereits vorhanden sind.
    
$select $db->prepare("SELECT `name`, `email`
                                       FROM `users`
                                       WHERE `name` = :name
                                       OR `email` = :email");
    
$select->execute([":name" => $name,
        
":email" => $email]);
    
$benutzer $select->fetch();

    
// Benutzereingaben überprüfen
    // Name - Länge überprüfen
    
$fehler["name"] = (strlen($name< 2) ? '<br>Der Name ist zu kurz!' ''// Name - Länge überprüfen
    // Name bereits vorhanden
    
$fehler["name"] = ($select->rowCount() > && $benutzer["name"] == $name) ? '<br>Der Name ist bereits vorhanden!' $fehler["name"];

    
// E-Mail-Adresse überprüfen
    
$fehler["email"] = (!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)) ? '<br>Die E-Mail-Adresse ist fehlerhaft!' '';
    
// E-Mail Adresse bereits vorhanden
    
$fehler["email"] = ($select->rowCount() > && $benutzer["email"] == $email) ? '<br>Die E-Mail-Adresse ist bereits vorhanden!' $fehler["email"];

    
// Passwort - Länge überprüfen
    
$fehler["passwort"] = (strlen($_POST["passwort"]) < 8) ? '<br>Das Passwort ist zu kurz!' '';
    
// Passwörter A/B überprüfen
    
$fehler["passwort"] = ($_POST["passwort"] != $_POST["passwortB"]) ? '<br>Die Passwörter sind unterschiedlich!' $fehler["passwort"];
}

// Formular erstellen
$formular '<form method="post">

<p>
 <label for="name">Name:</label>
 <input type="text" name="name" id="name" value="' htmlspecialchars($nameENT_HTML5'UTF-8') . '" autocomplete="name" required="required">
 <span class="pflichtfeld">* ' $fehler["name"] . '</span>
</p>

<p>
 <label for="email">E-Mail:</label>
 <input type="mail" name="email" id="email" value="' htmlspecialchars($emailENT_HTML5'UTF-8') . '" autocomplete="email" required="required">
 <span class="pflichtfeld">* ' $fehler["email"] . '</span>
</p>

<p>
 <label for="passwort">Passwort:</label>
 <input type="password" name="passwort" id="passwort" value="' htmlspecialchars($passwortENT_HTML5'UTF-8') . '" autocomplete="new-password" required="required">
 <span class="pflichtfeld">* ' $fehler["passwort"] . '</span>
</p>

<p>
 <label for="passwortB">Passwort:</label>
 <input type="password" name="passwortB" id="passwortB" value="' htmlspecialchars($passwortBENT_HTML5'UTF-8') . '" autocomplete="new-password" required="required">
 <span class="pflichtfeld">*</span> <small>(wiederholen)</small>
</p>

<p><button type="submit">Registrieren</button></p>

</form>';

// Wurden Daten über POST gesendet
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    
// Sind keine Eingabefehler vorhanden
    
if (implode(""$fehler) == "") {

        
// Passwort verschlüsseln
        
$passwort password_hash($_POST["passwort"], PASSWORD_BCRYPT);

        
// Benutzer in die DB-Tabelle eintragen
        
$insert $db->prepare("INSERT INTO `users`
                                        SET
                                          `name` = :name,
                                          `email`           = :email,
                                          `password`     = :passwort,
                                          `status`          = :status,
                                          `created_at`   = NOW(),
                                          `updated_at`  = NOW()");

        if (
$insert->execute([":name" => $name,
            
":email" => $email,
            
":passwort" => $passwort,
            
":status" => $FREISCHALTUNG])) {

            
// Den Status der Registrierung dem Benutzer mitteilen
            
if ($FREISCHALTUNG == 1) {

                
$ausgabe '<p>Sie wurden erfolgreich registriert.</p>
                       <p><a href="login.php">Hier geht es zur Anmeldung</a></p>';
            } else {
                
$ausgabe '<p>Sie wurden erfolgreich registriert.</p>
                        <p>Die Aktivierung erfolgt durch den Administrator.</p>
                        <p><a href="index.php">Hier geht es zur Startseite</a></p>';
            }
        }
    } else {

        
// Formular mit den Eingabefehlern anzeigen
        
$ausgabe $formular;
    }
} else {

    
// Formular anzeigen
    
$ausgabe $formular;
}
?>
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Registrierung</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<article>

<h1>Registrierung</h1>

<?=$ausgabe;?>

</article>

</body>
</html>

Die Anmeldung des Benutzers

Die Anmeldung des Benutzers erfolgt in der Datei: login.php. Das wichtigste daraus: Mit password_verify() wird das gesendete Passwort mit dem verschlüsselten Passwort aus der Datenbank verglichen. Weitere Schritte erklärt der Quelltext (fast) von selbst!

Quelltext:  login.php AusblendenKopierenLinkZeilen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php
/*
 * Anmeldung - login.php
 */

session_start();

// Verbindung zur Datenbank
include "connect.php";

$ausgabe "";

// Wurden Daten über POST gesendet
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    
// Name, Passwort und den Status des Benutzers auslesen
    
$select $db->prepare("SELECT `name`, `password`, `status`
                                       FROM `users`
                                       WHERE `name` = :name");
    
$select->execute([":name" => $_POST["name"]]);
    
$reg $select->fetch();

    
// Ist ein Eintrag vorhanden
    
if ($select->rowCount() == 1) {

        
// Name, Passwort und den Status überprüfen
        
if ($reg["name"] == $_POST["name"] &&
            
password_verify($_POST["passwort"], $reg["password"]) &&
            
$reg["status"] == "1") {

            
// Sessions setzen
            
$_SESSION["login"] = true;
            
$_SESSION["name"] = $reg["name"];

            
// Das Datum des aktuellen Besuchs in die DB-Tabelle eintragen
            
$db->query("UPDATE `users`
                        SET `updated_at` = NOW()
                        WHERE `name` = '" $reg["name"] . "'");

            
// Weiterleitung zur Datei: secret.php
            
header("Location: secret.php");
            exit;

        } else {

            
// Fehlerhafte Angaben
            
$ausgabe '<p><mark>Fehlerhafte Angaben!</mark></p>';
        }
    }
}

// Benutzer abmelden
if (isset($_GET["logout"])) {

    
// Session löschen
    
$_SESSION = [];
    
session_destroy();

    
// Weiterleitung zur Anmeldung
    
header("Location: login.php?logout_ok");
    exit;
}
?>
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Anmeldung</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<article>

<h1>Anmeldung</h1>

<?=$ausgabe;?>

<form method="post">

<p>
 <label for="name">Name:</label>
 <input type="text" name="name" id="name" autocomplete="name" required="required">
</p>

<p>
 <label for="passwort">Passwort:</label>
 <input type="password" name="passwort" id="passwort" autocomplete="current-password" required="required">
</p>

<p>
<button type="submit">Anmelden</button>
</p>

</form>

<?php
if (isset($_GET["logout_ok"])) {
    echo 
'<p>Abmeldung erfolgreich. <a href="index.php">Zur Startseite</a></p>';
}
?>

</article>

</body>
</html>

Die geschützte Seite

In jede Datei die geschützt werden soll, muss der folgende PHP-Code ganz an den Anfang der Datei. Es wird überprüft, ob die Session-Variable login existiert. Falls nicht, wird der Benutzer automatisch zur Anmeldung weitergeleitet.


<?php

/*
 * Dieses Script muss am Anfang jeder geschützten PHP-Datei stehen
 */

session_start();

if (!isset(
$_SESSION["login"])) {

 
// Zur Anmeldung weiterleiten
 
header("Location: login.php");
 exit;
}
?>

So, wie im folgenden Quelltext, sollte es dann aussehen (Zeilen: 1 - 14)

Quelltext:  secret.php AusblendenKopierenLinkZeilen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
/*
 * Geheim - secret.php
 */

session_start();

if (!isset(
$_SESSION["login"])) {

    
// Zur Anmeldung weiterleiten
    
header("Location: login.php");
    exit;
}
?>
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Geheim</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<article>

<h1>Geheim</h1>

<!-- Den Namen des Benutzers ausgeben -->
<p>
Herzlich willkommen
<q><?=htmlspecialchars($_SESSION["name"]);?></q>!
</p>

<!-- Der Benutzer kann sich hier abmelden -->
<p>
<a href="login.php?logout">Abmelden</a>
</p>

</article>

</body>
</html>

Die Startseite

Die Startseite index.php enthält zwei Hyperlinks, zur Anmeldung und zur Registrierung des Benutzers.

Quelltext:  index.php AusblendenKopierenLinkZeilen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Startseite</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<article>

<h1>Startseite</h1>

<p>
<a href="login.php">Anmeldung</a> - 
<a href="register.php">Registrierung</a>
</p>

</article>

</body>
</html>

Die CSS-Datei

In der Datei: style.css wird das aussehen der Seite bestimmt. Hier im Beispiel werden nur wenige Angaben benötigt.

body {
  font-family: Verdana, Arial, Sans-Serif;
  background: White;
}

article {
  background: Whitesmoke;
  width: 75%;
  padding: 10px 25px 25px 25px;
  margin: Auto;
}

h1 {
  font-weight: Normal;
}

a:link,
a:visited {
  color: Royalblue;
}

span.pflichtfeld {
  font-family: Arial, Tahoma, Verdana, Sans-Serif;
  font-size: 0.9rem;
  color: Red;
}

Die Verwaltung der Benutzer

Wenn man schon solch tolle Programme wie den Adminer oder phpMyAdmin hat, dann kann man dort spielend die Verwaltung der Benutzer machen.

[Bildschirmfoto] Die Verwaltung der Benutzer mit dem Programm 'Adminer'.
Die Verwaltung der Benutzer mit dem Programm 'Adminer'.

Es bleibt aber jedem selbst überlassen, eine eigene Benutzerverwaltung dafür zu schreiben.

➤ Gefällt Ihnen das Skript oder haben Sie einen Fehler gefunden? Dann freue ich mich auf Ihren Kommentar.

Tipps

MySQL-Webseitenschutz - Mit dem „MySQL-Webseitenschutz” lassen sich mehrere Webseiten schützen. Die Benutzerdaten werden in einer MySQL-Datenbank gespeichert.

Anmeldescript mit Bestätigungslink (Tutorial) - Ein Anmeldescript für Benutzer mit Bestätigungslink in der gesendeten E-Mail (Double Opt-in Abfrage).

Erster Eintrag in eine MySQL-Datenbank mit PHP - Eine Anleitung wie man ein Nachrichten-System mit einer MySQL (oder MariaDB)-Datenbank über PHP realisieren kann. Komplett mit Formularen zum eintragen, anzeigen und bearbeiten der Daten.