Anmeldescript mit Bestätigungslink (Tutorial)

[Bildschirmfoto / Grafik]
 Anmeldescript mit Bestätigungslink

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

Eigenschaften

Voraussetzung

Webserver (Linux) mit PHP 7.3 (oder höher), eine MySQL/MariaDB-Datenbank.

Benötigte Dateien:

  1. Konfiguration
  2. DB-Tabelle anlegen
  3. Registrierung
  4. Registrierung abschließen
  5. Administrator
  6. CSS
  7. Anleitung

Konfiguration

Hier ist es wichtig das korrekte Daten eingegeben werden damit es keine Probleme gibt!

Quelltext „konfig.phpKopierenAusblendenZeilen

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
<?php
/*
 * Konfiguration - Anmeldescript mit Bestätigungslink
 * werner-zenk.de
 */


// Benutzername - Administrator
$BENUTZERNAME "user";

// Passwort - Administrator
$PASSWORT "0000";

// E-Mail
// Eine beim Provider registrierte E-Mail Adresse!
$EMAIL "email@example.com";

// E-Mail Name
$EMAILNAME "";

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

// Der Benutzer hat X-Tage Zeit um seine
//  Registrierung (über E-Mail) freizuschalten
$FREISCHALTTAGE 7// 7

// Homepage-Name (wird in der E-Mail angezeigt!)
$HOMEPAGE_NAME "Example.com"// Example.com

// Betreff der E-Mail (Benutzer)
$BETREFF "Registrierung";

// Inhalt der E-Mail (Benutzer)
// Die Platzhalter bitte nicht entfernen!
$NACHRICHT "Registrierung bei {:HOMEPAGE:}., am {:DATUM:}

Klicken Sie auf den folgenden Link um Ihre Registrierung abzuschließen: 
{:REGISTER:}

Bestätigen Sie innerhalb von {:FREISCHALTTAGE:} Tagen Ihre Registrierung.

Diese E-Mail wurde vom System automatisch versendet.";

// Betreff der E-Mail (Admin.)
$BETREFF_ADMIN "Neue Registrierung";

// Nachricht der E-Mail (Admin.)
$NACHRICHT_ADMIN "Es wurde eine neue Registrierung eingetragen.";

// Name der Datenbank-Tabelle
$TBL_NAME "subscribe";

// Absoluter Pfad zum Verzeichnis
$PFAD = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' 'https://' 'http://') . $_SERVER['HTTP_HOST'] .
 
rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\');

// PHP Fehlermeldungen lokal anzeigen
if ($_SERVER["SERVER_NAME"] == 'localhost') {
 
error_reporting(E_ALL);
 
ini_set("display_errors"true);
}

/* 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('<p>Verbindung zur Datenbank fehlgeschlagen!</p>$e->getMessage());
}

DB-Tabelle anlegen

Nach dem Aufrufen dieser Datei über den Browser, sollte: Die Tabelle wurde angelegt. erscheinen. Es wird eine Tabelle mit dem Namen subscribe angelegt mit sechs Spalten.

Quelltext „install.phpKopierenAusblendenZeilen

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
<?php
/*
 * DB-Tabelle anlegen - Anmeldescript mit Bestätigungslink
 * werner-zenk.de
 */


include "konfig.php";
$ausgabe '';

try {
 
$db->exec("CREATE TABLE IF NOT EXISTS `" $TBL_NAME "` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `status` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Nein',
  `datum` date NOT NULL,
  `register` int(12) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");

 
$ausgabe '<p>&#10004; Die Tabelle wurde angelegt.<br>
  <a href="register.php">Registrieren</a></p>';
}
catch (
PDOException $e) {
 
$ausgabe '<p>&#10008; Fehler beim anlegen der Tabelle!</p>.
  
$e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Datenbank-Tabelle anlegen</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<h2>Datenbank-Tabelle anlegen</h2>

<?=$ausgabe;?>

</body>
</html>

Registrierung

Hier werden die Eingaben des Benutzers verarbeitet. Zuerst wird überprüft ob der Name des Benutzers oder seine E-Mail Adresse bereits in der DB-Tabelle vorhanden sind. Und ob die E-Mail Adresse das richtige Format hat

Sodann wird der Benutzer in die DB-Tabelle eingetragen. Es wird dann eine E-Mail erstellt und versendet. Der Benutzer erhält noch eine Meldung das die E-Mail unterwegs ist und er soll den Link innerhalb von 7 Tagen bestätigen.

Quelltext „register.phpKopierenAusblendenZeilen

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
<?php
/*
 * Registrierung - Anmeldescript mit Bestätigungslink
 * werner-zenk.de
 */


include "konfig.php";

// Variablen setzen
$ausgabe '';
$benutzerName $_POST["name"] ?? "";
$benutzerEmail $_POST["email"] ?? "";
$korrektur "";
$benutzereingabe = [
                
"name" => "",
                
"email" => "",
               ];

if (
$_SERVER["REQUEST_METHOD"] == "POST") {

  
// Benutzername überprüfen ob dieser bereits vorhanden ist
  
$select $db->prepare("SELECT `name`, `email`
                                       FROM `" $TBL_NAME "`
                                       WHERE `name` = :name
                                       OR `email` = :email");
  
$select->execute([':name' => $benutzerName,
                              
':email' => $benutzerEmail]);
  
$benutzer $select->fetch();

 
// Benutzereingaben (Pflichtfelder) überprüfen
 
$benutzereingabe["name"] = (strlen($benutzerName< 5) ? '<br>Der Name ist zu kurz!' '';
 
$benutzereingabe["name"] = ($select->rowCount() > 0) ? '<br>Der Name ist bereits vorhanden!' $benutzereingabe["name"];

  
$benutzereingabe["email"] = (!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL))  ? '<br>Die E-Mail-Adresse ist fehlerhaft!' '';
  
$benutzereingabe["email"] = ($select->rowCount() > 0) ? '<br>Die E-Mail-Adresse ist bereits vorhanden!' $benutzereingabe["email"];

  if (!empty(
implode(""$benutzereingabe))) {
   
$korrektur '<h3 class="markierung">&#10008; Bitte korrigieren Sie Ihre Eingaben!</h3>';
  }
}

// Formular erstellen
$formular $korrektur '
<form action="register.php" method="post" accept-charset="UTF-8">

<p><label>Name: 
<span class="markierung">&#10034; ' $benutzereingabe["name"] . '</span> <br>
<input type="text" name="name" value="' $benutzerName '" size="35" required="required"></label>
</p>

<p><label>E-Mail: 
<span class="markierung">&#10034; ' $benutzereingabe["email"] . '</span> <br>
<input type="email" name="email" value="' $benutzerEmail '" size="35" required="required"></label>
</p>

<p>
 <input type="submit" value="Absenden">
</p>
</form>
';

if (
$_SERVER["REQUEST_METHOD"] == "POST") {
 if (!empty(
implode(""$benutzereingabe))) {

  
// Zeitstempel erzeugen
  
$zeitstempel time();

  
// Benutzer in die DB eintragen
  
$insert $db->prepare("INSERT INTO `" $TBL_NAME "`
  SET
    `name`      = :name,
    `email`      = :email,
    `register`   = '" $zeitstempel "',
    `datum`     = NOW()");
   if (
$insert->execute([':name' => $benutzerName,
                                  
':email' => $benutzerEmail])) {

    
// Nachricht an den Benutzer (Platzhalter ersetzen)
    
$NACHRICHT strtr($NACHRICHT,
        [
"{:HOMEPAGE:}" => $HOMEPAGE_NAME
         
"{:DATUM:}" => date("d.m.Y \u\m H:i"$zeitstempel) . " Uhr",
         
"{:REGISTER:}" => $PFAD "/register_ok.php?uid=" $zeitstempel,
         
"{:FREISCHALTTAGE:}" => $FREISCHALTTAGE]);

    
// E-Mail an den Benutzer versenden
    // Besser wäre es, hier den PHPMailer zu verwenden!
    
mb_internal_encoding("UTF-8");
    
$BETREFF mb_encode_mimeheader($BETREFF"UTF-8""Q");
    
$KOPFZEILE "MIME-Version: 1.0;\nFrom: " mb_encode_mimeheader($EMAILNAME"UTF-8""Q") .
     
"<$EMAIL ">"\nContent-Type: text/plain; Charset=UTF-8;\n";

    if (
mail($benutzerEmail$BETREFF$NACHRICHT$KOPFZEILE)) {

     
// Nachricht ausgeben
     
$ausgabe '<h2>Vielen Dank für die Registrierung!</h2>
      <p>
       &#10004; Wir haben eine E-Mail gesendet an: ' htmlspecialchars($benutzerEmail) . '. <br>
       Bitte klicken Sie auf den Link in der E-Mail, um Ihr Konto zu bestätigen.
      </p>
      <p>
       Bestätigen Sie innerhalb von <strong>$FREISCHALTTAGE ' Tagen</strong> <br>
       dann ist die Registrierung abgeschlossen.
      </p>
      <p>
       Wenn Sie die E-Mail innerhalb von 24 Stunden noch immer nicht erhalten haben,<br>
       stellen Sie bitte sicher, dass Sie Ihren Junk-E-Mail-Ordner überprüft haben.
      </p>';

     
// E-Mail an den Administrator versenden
     
mb_internal_encoding("UTF-8");
     
$BETREFF_ADMIN mb_encode_mimeheader($BETREFF_ADMIN"UTF-8""Q");
     
$KOPFZEILE "MIME-Version: 1.0;\nFrom: " mb_encode_mimeheader($benutzerName"UTF-8""Q") .
      
"<$benutzerEmail ">"\nContent-Type: text/plain; Charset=UTF-8;\n";
     
mail($EMAIL$BETREFF_ADMIN$NACHRICHT_ADMIN$KOPFZEILE);

   }
  }
 }
 else {

  
// Eingabefehler und Formular 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>

<h2>Registrierung</h2>

<?=$ausgabe;?>

</body>
</html>

Registrierung abschließen

Diese Datei ruft der Benutzer auf, wenn er den Link (Bestätigungslink) in der E-Mail anklickt.

Es wird nun überprüft ob sich der Benutzer in der DB-Tabelle befindet und ob der Zeitstempel innerhalb von 7 Tagen liegt. Wenn nun alles korrekt ist, wird der Status des Benutzers in der DB-Tabelle geändert.

Quelltext „register_ok.phpKopierenAusblendenZeilen

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
<?php
/*
 * Registrierung abschließen - Anmeldescript mit Bestätigungslink
 * werner-zenk.de
 */


include "konfig.php";
$ausgabe "";

// Link-Bestätigung der Registrierung (über E-Mail)
if (isset($_GET["uid"])) {
 if (
ctype_digit($_GET["uid"])) {
  
$uid htmlspecialchars($_GET["uid"]);

  
// Überprüfen ob das Eintragsdatum in der DB vorhanden ist
  
$select $db->prepare("SELECT `register` FROM `" $TBL_NAME "` WHERE `register` = :uid");
  
$select->execute([':uid' => $uid]);
  
$reg $select->fetch();

  
// Datensatz vorhanden
  
if ($select->rowCount() > 0) {

   
// Ablauffrist größer als die Freischalttage
   
if ((floor((time() - $reg["register"]) / 86400)) > $FREISCHALTTAGE) {

    
// Registrierung abbrechen - Benutzer entfernen
    
$db->query("DELETE FROM `" $TBL_NAME "` WHERE `register` = '" $reg["register"] . "'");

    
// Fehler, die Registrierung ist abgelaufen
    
$ausgabe '<h3 class="markierung">Fehler bei der Registrierung!</h3>
     <p>&#10008; Die Zeit um Ihre Registrierung freizuschalten ist leider abgelaufen (' $FREISCHALTTAGE ' Tage).</p>
     <p><a href="register.php">Bitte registrieren Sie Sich erneut</a></p>';
   }
   else {

    
// Registrierung abschließen
    
$db->query("UPDATE `" $TBL_NAME "` SET `status` = 'Ja'  WHERE `register` = '" $reg["register"] . "'");

    
// Registrierung erfolgreich
    
$ausgabe '<h3>Registrierung erfolgreich</h3>
     <p>&#10004; Ihre Registrierung wurde erfolgreich abgeschlossen.</p>';
   }
  }
  else {

   
// Datensatz nicht vorhanden -> Registrierung erforderlich
   
$ausgabe '<h3 class="markierung">Fehler bei der Registrierung!</h3>
      <p>&#10008; Sie müssen sich <a href="register.php">registrieren</a></p>';
  }
 }
}
?>
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Registrierung abschließen</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<h2>Registrierung abschließen</h2>

<?=$ausgabe;?>

</body>
</html>

Administrator

[Bildschirmfoto / Grafik]
 Anmeldescript mit Bestätigungslink

Hier werden die registrierten Benutzer angezeigt und ob diese bereits den Bestätigungslink getätigt haben. Außerdem die E-Mail der Benutzer mit dem Datum der Registrierung. Der Admin. hat die Möglichkeit einzelne Benutzer zu löschen.

Quelltext „admin.phpKopierenAusblendenZeilen

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
<?php
/*
 * Administrator - Anmeldescript mit Bestätigungslink
 * werner-zenk.de
 */


session_start();
include 
"konfig.php";
$ausgabe '';

// Anmeldung
if (isset($_POST["anmeldung"])) {
 if (
$_POST["benutzername"] == $BENUTZERNAME &&
     
$_POST["passwort"] == $PASSWORT) {
  
$_SESSION["administrator"] = true;
 }
}

// Abmeldung
if (isset($_GET["abmelden"])) {
 
session_destroy();
 
header("Location: admin.php");
 exit;
}

// Benutzer löschen
if (isset($_POST["delete"])) {
 if (isset(
$_POST["id"])) {
  
$params $_POST["id"];
  
$placeholder implode(','array_fill(0count($params), '?'));

  
$stmt $db->prepare("DELETE FROM `" $TBL_NAME "` WHERE `id` IN (" $placeholder ")");
  if (
$stmt->execute($params)) {
   
$ausgabe .= '<p>&#10004; Die Daten wurden gelöscht.</p>';
  } 
 }
}

// Datensätze auslesen
$select $db->query("SELECT `id`, `name`, `email`, `status`, `datum`
                                  FROM `" $TBL_NAME "`
                                  ORDER BY `datum` DESC");
$personen $select->fetchAll();

// Formular mit einer HTML-Tabelle
$ausgabe .= '<form action="admin.php" method="post">
<table id="tabelle">
 <tr>
  <th>#</th>
  <th title="Name des Benutzers">Name</th>
  <th title="E-Mail Adresse">E-Mail</th>
  <th title="Bestätigung der Registrierung">Status</th>
  <th title="Datum der Registrierung">Datum</th>
  <th title="Benutzer auswählen">&#128473;</th>
 </tr>';

// Ausgabe
foreach ($personen as $nr => $person) {

 
// Datum in Variablen aufteilen
 
sscanf($person["datum"], "%4s-%2u-%2u"$jahr$monat$tag);

 
// E-Mail Adresse verlinken
 
$email '<a href="mailto://' htmlspecialchars($person["email"]) . '" title="E-Mail senden">$person["email"] . '</a>';

 
// Tabellenspalten
 
$ausgabe .= '<tr>
  
'<td>. ($nr+1) . '</td>.
  
'<td>htmlspecialchars($person["name"]) . '</td>.
  
'<td>$email '</td>.
  
'<td>$person["status"] . '</td>.
  
'<td>$tag '.' $monat '.' $jahr '</td>
  
'<td><input type="checkbox" name="id[]" value="' $person["id"] . '"></td></tr>';
}
$ausgabe .= '</table>
<p>
 <input type="submit" name="delete" value="Markierte Benutzer löschen">
</p>

<p>
 <a href="?abmelden">Abmelden</a>
</p>
</form>';

// Anmeldung
if (!isset($_SESSION["administrator"])) {
 
$ausgabe '<form action="admin.php" method="post">
<h3>Anmeldung</h3>

<p>
<label>Benutzername: <span class="markierung">&#10034;</span><br>
 <input type="text" name="benutzername" size="35" required="required"></label>
</p>

<p><label>Passwort: <span class="markierung">&#10034;</span><br>
 <input type="password" name="passwort" size="35" required="required"></label>
</p>

<input type="submit" name="anmeldung" value="Anmelden">
 </form>';
}
?>
<!DOCTYPE html>
<html lang="de">
 <head>
  <meta charset="UTF-8">
  <title>Administrator</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link rel="stylesheet" href="style.css">
 </head>
<body>

<h2>Administrator</h2>

<?=$ausgabe;?>

</body>
</html>

CSS

In dieser Datei wird das aussehen der Seiten bestimmt. Hier im Beispiel werden nur wenige Angaben benötigt.

Quelltext style.css

body {
 font-family: Verdana, Arial, Sans-Serif;
 font-size: 0.90rem;
 background-color: #F5F5F5;
 margin: 25px;
 cursor: Default;
}

h2, h3 {
 font-weight: Normal;
}

.markierung {
 color: #FF0000;
}

table#tabelle {
 background-color: #FFFFFF;
 border-collapse: Separate;
 border-spacing: 3px;
 table-layout: Auto;
}

table#tabelle th,
table#tabelle td {
 border: Solid 1px #2284E6;
 padding: 5px;
}

table#tabelle tr:nth-child(even) {
 background-color: #F5FAFE;
 transition: background-color 0.3s;
}

table#tabelle tr:nth-child(odd) {
 background-color: #FFFFFF;
 transition: background-color 0.3s;
}

table#tabelle tr:hover {
 background-color: #F5F5F5;
}

table#tabelle th {
 background-color: #DAEDFC;
 position: Sticky;
 top: 0px;
}

a:link, a:visited {
 color: #2284E6
}

Anleitung

Quelltext lies_mich.txt

Anleitung

1. In der Datei: "konfig.php" die benötigten Angaben richtig ausfüllen.
2. Dateien auf dem Webserver hochladen.
3. Datei: "install.php" über dem Browser aufrufen.
4. Fertig

Viel Spaß damit!
Werner

werner-zenk.de

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