Cloudflare Turnstile ist ein kostenloses Tool, das CAPTCHAs ersetzt. Turnstile bietet Website-Besuchern ein frustrationsfreies, CAPTCHA-freies Web-Erlebnis. Darüber hinaus verhindert Turnstile missbräuchliche Verwendung und bestätigt, dass die Besucher echt sind – ohne den Datenschutz zu gefährden und ganz ohne die schlechte Nutzererfahrung, die mit CAPTCHAs einhergeht. Weiters ist dieses viel zuverlässiger als beispielsweise Google reCAPTCHA
In dieser Anleitung zeigen wir dir, wie du Turnstile in ein HTML Formular einbaust und das ganze mit PHP validierst und anschließend das Formular auch noch mit der simplen PHP mail Funktion oder einem SMTP Mailer versenden kannst.
Das Ganze wird anhand von einem simplen Beispiel erklärt:
Bevor wir uns jetzt dem Einbinden auf der Website widmen, müssen man die Keys von Cloudflare für das Turnstile erzeugen lassen. Dazu muss man einen Account bei Cloudflare haben.
Nachdem man sich angemeldet hat, klickt man auf Turnstile und anschließend auf "Add Site" um die Website hinzuzufügen.
Im nächsten Schritt gibst du dem Turnstile einen Namen und stellst die Domain bereit. Falls man das Captcha komplett verschwinden lassen will, kann man dieses hier auf Invisible stellen. Beim Non-Interactive Modus muss der Nutzer nichts machen, um das Captcha zu lösen. Dennoch wird empfohlen den gemanaged Modus zu verwenden. Die Pre-clearance kann je nach Verwendungszweck ausgeschalten werden. Für ein Formular empfiehlt es sich diesen auszuschalten. Jetzt nur noch auf Create klicken und die Keys sind bereit.
Jetzt haben wir die Keys und können mit dem einbinden beginnen. Es gibt 2 Keys einmal den öffentlichen und auch den Privaten.
Beim Einbinden auf der Website unterscheidet man zwischen der Client seitigen Einbindung und der Server seitigen Einbindung. Um einen vollständigen und sicheren Schutz vor Spam und Bots zu gewährleisten ist es notwendig beides zu machen. Trotzdem wird diese Anleitung in Clientseitige und Serverseitige Einbindung unterteilt.
Um das Cloudflare Captcha zu verwenden müssen wir zuerst diesen Code im Head-Bereich einfügen.
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" defer></script>
Als Nächstes muss das Element selbst im Formular eingefügt werden. Dabei ist zu beachten, dass anstelle von "Dein öffentlicher Key" dein generierter Clientseitiger Key eingegeben werden muss. Jetzt sollte auf deiner Seite das Widget schon sichtbar sein.
Da ich das ganze anhand von einem Beispiel erkläre, ist hier der Beispielcode für das obige Formular:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Formular</title>
<!-- Cloudflare API script -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" defer></script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
form {
background-color: #fff;
padding: 40px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
width: 400px;
}
label {
display: block;
margin-bottom: 10px;
}
input[type="text"],
input[type="email"],
textarea {
width: 100%;
padding: 8px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type="submit"] {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<form action="send.php" method="post" id="myForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">E-Mail:</label>
<input type="email" id="email" name="email" required>
<label for="message">Nachricht:</label>
<textarea id="message" name="message" rows="4" required></textarea>
<!-- Add your public key -->
<div class="cf-turnstile" data-sitekey="Dein öffentlicher Schlüssel"></div>
<input type="submit" value="Absenden" id="submitButton">
</form>
</body>
</html>
Somit ist die Clientseitige Integrierung jetzt fertig.
Um jetzt nochmal ganz sicher zu kontrollieren, dass es sich bei dem Besucher nicht um einen Bot handelt wird das Captcha Serverseitig auch nochmal validiert. Diesen Schritt habe ich mit einfachem PHP gemacht. Im weiteren Verlauf dieser Anleitung zeige ich, wie man nur die Serverseite Validierung mit PHP macht, wie man es direkt mit der PHP mail Funktion verwenden kann, und dann auch noch wie wir professioneller die Formulareingabe über SMTP verschicken könnnen um eine sichere Ankunft der Nachricht bei den meisten E-Mail-Anbietern zu gewährleisten.
Wenn du vorhast diesen Code für anderwärtige Projekte zu verwenden, zum Beispiel für ein Login, stelle ich hier diesen Code auch zur Verfügung. Falls du nur ein Formular verwenden willst, welches die Inhalte über E-mail weiterleitet, kannst du diesen Teil überspringen, da der Code in den folgenden Fällen sowieso integriert ist.
<?php
$turnstile_secret = 'YourSecretKey';
$turnstile_response = $_POST['cf-turnstile-response'];
$url = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
$post_fields = "secret=$turnstile_secret&response=$turnstile_response";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
$response = curl_exec($ch);
curl_close($ch);
$response_data = json_decode($response);
if ($response_data->success != 1) {
header("Location: /login.php?error=recaptcha");
exit;
}
?>
Hier ist der Code für die send.php Datei, welche die Validierung und anschließende Versendung mit der einfachen PHP-Mail-Funktion. Da diese aber meist nur auf der eigenen Domain verlässlich funktioniert empfiehlt es sich, die danach folgende SMTP Funktion zu verwenden. Trotzdem steht hier der Code für euch bereit. Wichtig ist hier, dass diese Datei gleich heißt wie der Action Tag in deinem Formular sonst funktionert hier nichts. Damit das jetzt funktioniert, musst du noch den SecretKey an der richtigen Stelle eintragen und die Empfänger E-mail angeben. Weiters kann auch noch der Betreff gewählt werden. Falls du andere Formularfelder hast, ist es wichtig diese Funktion abzuändern. Wenn du nicht weißt, wie das funktioniert, frag einfach ChatGPT.
<?php
// Definiere deinen geheimen Schlüssel
$secretKey = 'YourSecretKey';
// Antwort-Token vom Formular erhalten
$responseToken = $_POST['cf-turnstile-response'];
// IP-Adresse des Benutzers abrufen
$remoteIP = $_SERVER['REMOTE_ADDR'];
// Die Daten für die POST-Anfrage vorbereiten
$data = array(
'secret' => $secretKey,
'response' => $responseToken,
'remoteip' => $remoteIP
);
// Curl-Sitzung initialisieren
$ch = curl_init();
// Die Curl-Optionen setzen
curl_setopt($ch, CURLOPT_URL, 'https://challenges.cloudflare.com/turnstile/v0/siteverify');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Die POST-Anfrage ausführen
$response = curl_exec($ch);
// Curl-Sitzung schließen
curl_close($ch);
// Die JSON-Antwort dekodieren
$result = json_decode($response, true);
// Überprüfen, ob die Verifizierung erfolgreich war
if ($result && isset($result['success']) && $result['success'] === true) {
// Verifizierung erfolgreich, mit dem Senden der E-Mail fortfahren
// Empfänger-E-Mail-Adresse festlegen
$empfaenger = 'Empfänger-Mail-Adresse Eingeben';
// Betreff
$betreff = 'Formularübermittlung';
// Nachricht
$nachricht = "Name: ".$_POST['name']."\n"."E-Mail: ".$_POST['email']."\n"."Nachricht: ".$_POST['message'];
// E-Mail senden
if (mail($empfaenger, $betreff, $nachricht)) {
echo '<script>';
echo 'alert("E-Mail erfolgreich versendet");';
echo '</script>';
} else {
echo '<script>';
echo 'alert("Captcha-Verifizierung erfolgreich, aber E-Mail konnte nicht gesendet werden. Bitte versuche es erneut.");';
echo '</script>';
}
} else {
// Verifizierung fehlgeschlagen, Fehler behandeln
echo '<script>';
echo 'alert("Captcha-Verifizierung fehlgeschlagen. Bitte versuche es erneut.");';
echo '</script>';
}
?>
Hier ist der Code für die send.php Datei mit SMTP-Mail-Funktion. Eigentlich funktioniert es hier gleich wie in der oberen nur das die Mail über den SMTP Server versendet wird. Um dies zu verwenden braucht man zwei Dinge: Den SMTP Zugang sowie den PHPMailer. Den aktuellsten PHPMailer kannst du hier herunterladen oder einfach den in dem Beispiel verwendeten PHPMailer kopieren. Danach musst du ihn richtig in deine Ordnerstruktur einbinden. Lade dir die Beispieldatei herunter um zu verstehen, wo du die Ordner platzieren musst. Im nächsten Schritt musst du einfach die Daten austauschen: Den geheimen Schlüssel hinzufügen, den SMTP Server hinzufügen, sowie den SMTP Nutzernamen als auch das SMTP Passwort. Da es schon sehr viele Gute Anleitungen für sowas gibt, zeige ich jetzt nicht wie man an diese Daten kommt, aber hier ist eine Videoanleitung . Wie auch schon zuvor funktioniert das Versenden der Inhalte nur wenn es das genau gleiche Formular wie oben ist, falls das nicht zutrifft diese Datei bitte anpassen oder ChatGPT fragen.
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// PHPMailer einbinden
require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
// Definiere deinen geheimen Schlüssel
$secretKey = 'Dein geheimer Schlüssel';
// Antwort-Token vom Formular erhalten
$responseToken = $_POST['cf-turnstile-response'];
// IP-Adresse des Benutzers abrufen
$remoteIP = $_SERVER['REMOTE_ADDR'];
// Die Daten für die POST-Anfrage vorbereiten
$data = array(
'secret' => $secretKey,
'response' => $responseToken,
'remoteip' => $remoteIP
);
// Curl-Sitzung initialisieren
$ch = curl_init();
// Die Curl-Optionen setzen
curl_setopt($ch, CURLOPT_URL, 'https://challenges.cloudflare.com/turnstile/v0/siteverify');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Die POST-Anfrage ausführen
$response = curl_exec($ch);
// Curl-Sitzung schließen
curl_close($ch);
// Die JSON-Antwort dekodieren
$result = json_decode($response, true);
// Überprüfen, ob die Verifizierung erfolgreich war
if ($result && isset($result['success']) && $result['success'] === true) {
// Verifizierung erfolgreich, mit dem Senden der E-Mail fortfahren
// PHPMailer instanziieren
$mail = new PHPMailer(true);
try {
// Servereinstellungen
$mail->isSMTP();
$mail->Host = 'SMTP-Server-Adresse'; // SMTP-Serveradresse eingeben
$mail->SMTPAuth = true;
$mail->Username = 'SMTP Benutzername'; // Benutzername für die SMTP-Authentifizierung
$mail->Password = 'SMTP Passwort'; // Passwort für die SMTP-Authentifizierung
$mail->Port = 587;
$mail->SMTPSecure = 'tls';
// Festlegen des Absenders (From) mit der E-Mail-Adresse und dem Namen
$mail->setFrom('Absender E-Mail Aderesse', 'Betreff');
$mail->addAddress('Empfänger-Mail-Adresse Eingeben'); // Empfänger hinzufügen
// Inhalt
$mail->isHTML(false);
$mail->Subject = 'Formularübermittlung';
$mail->Body = "Name: ".$_POST['name']."\n"."E-Mail: ".$_POST['email']."\n"."Nachricht: ".$_POST['message'];
$mail->send();
// Hier kannst du zwischen einer Weiterleitung oder einem simplen Alert entscheiden
// header("Location: bestaetigung.html");
echo '<script>';
echo 'alert("Email erfolgreich versendet");';
echo '</script>';
} catch (Exception $e) {
echo '<script>';
echo 'alert("Captcha-Verifizierung erfolgreich, aber E-Mail konnte nicht gesendet werden. Bitte versuche es erneut.");';
echo '</script>';
}
} else {
// Verifizierung fehlgeschlagen, Fehler behandeln
echo '<script>';
echo 'alert("Captcha-Verifizierung fehlgeschlagen. Bitte versuche es erneut.");';
echo '</script>';
}
?>
So das wars jetzt auch mit dieser Anleitung, falls du noch Fragen hast oder gerne hättest, dass ich die Integrierung für dich übernehme, kannst du dich gerne in dem folgenden Formular bei mir melden.