Captcha mit PHP erstellen
Wenn Sie Ihren Usern Communityfunktionen anbieten, ein Mailformular oder eine andere Dienstleistung zur Verfügung stellen kennen Sie sicherlich das Problem: Wie kann ich sicherstellen, dass die Benutzer die meinen Service nutzen auch wirklich Benutzer und keine Scripte sind, die meine Leistung für eigene Zwecke missbrauchen.
Die Idee
Ansatzpunkt für diese Unterscheidung kann nur der Mangel automatisierter Aufrufe sein, streng nach Ablaufplan zu arbeiten und zufällige Ereignisse nicht vorhersehen zu können. Daher hat sich in der Praxis in letzter Zeit zunehmen die Methode durchgesetzt den Benutzer ein individuelles Merkmal das nur für das menschliche Auge lesbar ist, wiedergeben zu lassen. Diese Sicherungsmethode generiert ein Bild, welches eine zufällige Zeichenfolge enthält, die von Benutzer abgetippt werden muss. Die ursprüngliche Zeichenfolge und die Eingabe des Benutzers werden später verglichen, um festzustellen, ob die Anfrage tatsächlich von einem “echten” Benutzer kam.
Die Umsetzung
In der Theorie eine sicherlich schöne Idee, aber wie lässt sich das Ganze praktisch umsetzen?
Zunächst benötigen wir einen zufälligen - im Beispiel sechsstelligen - Wert, der im Sicherheitsfeld angezeigt werden soll. Diesen lassen wir automatisch erstellen indem wir folgende Zeilen in die Datei formular.php schreiben.
<?php
// zufällige Zahl zwischen 100000 und 999999 ermitteln
srand();
$wert = rand(100000, 999999);
?>
Nachdem wir nun einen sechsstelligen Wert in einem String gespeichert haben brauchen wir natürlich noch ein Bild, in dem dieser wiedergegeben werden soll. Dazu nutzen wir die Funktionen der GD-Bibliothek, die auf dem Server installiert sein muss. Sollte dies nicht der Fall sein, kann Ihnen, sofern Sie keinen eigenen Server besitzen, nur Ihr Provider weiterhelfen und die benötigte Bibliothek gegebenenfalls installieren.
<?php
// Erstellen eine 40 mal 100 px großen Bildes
$bild = imagecreate(100,40);
// Farben definieren
$schwarz = imagecolorallocate($bild,0,0,0);
$weiss = imagecolorallocate($bild,255,255,255);
// Schrift einfügen
imagestring($bild,20,20,10,$wert,$weiss);
// Störlinien setzen
imageline($bild,0,30,100,10,$weiss);
imageline($bild,0,10,100,30,$weiss);
imageline($bild,20,0,80,40,$weiss);
// Type im Header definieren und Bild ausgeben
header(“Content-Type: image/jpeg”);
imagejpeg($bild);
// Bild löschen
imagedestroy($bild);
?>
Wir erstellen eine neue Datei namens captcha.php und definieren darin zuerst ein Bild in der Größe 40 x 80 px, die benötigten Farben (RGB) für Hintergrund (schwarz), Schrift (weiß) und Störlinien (auch weiß). Letztere sollen die Lesbarkeit des Bild für OCR Software erschweren. Im Anschluss daran wird das Bild später mit der entsprechenden Schrift versehen. Dann setzen wir die Störlinien mit imageline(Bild, x_start, y_start, x_ende, y_ende, Farbe). Anschließend wird noch der Typ der Datei definiert und das fertige Bild mit dem Funktionsaufruf imagejpeg($bild) ausgegeben. Zu guter letzt löschen wir das jetzt übermittelte Bild mit imagedestroy(Bild).
Nachdem wir nun ein Captcha erstellen lassen können müssen wir dieses noch sinnvoll in ein Formular einbinden und prüfen, ob die Eingabe des Benutzers mit der im Captcha angezeigten Zahl übereinstimmt.
<?php
// Prüfung ob captcha == eingabe
if (isset($_POST[’submit’]))
{
if ($_POST[‘wert’] == $_POST[‘testwert’])
echo ‘Prüfung erfolgreich!’;
else
echo ‘Prüfung erfolglos!’;
}
// Formular
else
{
// zufällige Zahl zwischen 100000 und 999999 ermitteln
srand();
$wert = rand(100000, 999999);
// Formular ausgeben
echo ‘<form action=”formular.php” method=”post”>’;
echo ‘<input type=”text” name=”testwert” maxlength=”6″ /><br /><br />’;
// Captcha anfordern mit dem entprechenden Wert anfordern
echo ‘<img src=”captcha.php?wert=’.$wert.‘” /><br /><br />’;
echo ‘<input type=”hidden” name=”wert” value=”‘.$wert.‘” />’;
echo ‘<input type=”submit” name=”submit” value=”Eingabe Prüfen” />’;
echo ‘</form>’;
}
?>
Hierzu wechseln wir wieder in die Datei formular.php und erweitern diese um das gewünschte Formular. Das Captcha wird mit
<img src=”captcha.php?wert=’.$wert.’” mce_src=”captcha.php?wert=’.$wert.’” />
eingebunden, wobei wir an den Aufruf der Datei captcha.php den vorher ermittelten Wert anfügen, der ja im Bild angezeigt werden soll. Der Wert wird gleichzeitig als String per hidden Feld übermittelt. Natürlich könnte man hier auch den Wert in eine Datenbank schreiben und einen anderen Schlüssel übermitteln, anhand dessen der Wert zum Vergleich später wieder ausgelesen wird. Für den Fall, dass eine Eingabe übermittelt wurde
if (isset($_POST[’submit’]))
werden die Zahl aus dem Captcha und die Eingabe des Benutzers verglichen. Sollten diese übereinstimmen kann dann eine beliebige Aktion ausgeführt werden. Wurde noch keine Eingabe übermittelt wird das Formular angezeigt.
info: Bitte unbedingt darauf achten, dass wir hier aus gründen der Übersicht auf eine Datenbankanbindung verzichtet haben. Sicherer ist es natürlich die Zufallszahl in einer Datenbank abzuspeichern ohne dabei diese im Quellcode sichtbar zu veröffentlichen.
Man kann die Zufallszahl auch einfach in einer Sessions speichern.. das macht imho weitaus weniger aufwand als die Datenbanklösung ![]()
Sehr nette Anleitung,
wobei, wenn man es so macht, wie hier beschrieben, kann es passieren, dass der Code im Bild nicht angezeigt wird. Sollte dies der Fall sein, müsste die captcha.php mit $wert = $_GET[’wert’] erweitert werden. Man setzt es an den Anfang und alles ist im grünen Bereich.
Hallo,
wollte den Spam-Schutz in mein Gästebuch integrieren. Folgende Probleme treten auf, die ich nicht lösen kann.
1. // Prüfung ob captcha == eingabe
if (isset($_POST[’submit’]))
{
if ($_POST[‘wert’] == $_POST[‘testwert’])
echo ‘Prüfung erfolgreich!’;
else
echo ‘Prüfung erfolglos!’;
In der Zeile else wird durch den Browser eine Fehlermeldung ausgegeben und die Seite nicht angezeigt.
2. echo ‘’; bei dieser Schreibweise erscheint auf dem caotchat.php-Bild vor und hinter der generierten Zahl ein a mit einem Punkt (a .568532. a).
Erst die Änderung der Schreibwiese wie folgt, konnte den Fehler beheben.
echo ‘’;
Wie o.g. konnte ich die Auswertung der generierten Zahl mit der eingegebenen nicht zum Laufen bringen.
Unter http://www.urologenpraxis-berthold.de/FourJjeh/gaestebuch/gaestehuch-fourjjeh.php wird ab der Zeile 408 Eine Fehlermeldung ausgegeben.
Auch ist mir nicht klar, wie ich, falls die Funktion mal laufen sollte der Senden-Modus mit der von Ihnen vorgeschlagenen Funktion,
f (isset($_POST[’submit’]))
eingebunden werden kann?
Für eine Hilfe wäre ich sehr dankbar.
M.f.G. Mitsch