reCAPTCHA Tutorial

reCAPTCHA: Der Spam-Schutz für Dein Kontaktformular

Lange lange hat es gedauert, endlich zeigen wir, wie es geht – reCAPTCHA: Der Spam-Schutz für Dein Kontaktformular. Wir zeigen heute, wie Du Dein Kontaktformular vor ungewollter Nutzung schützen kannst. Dies ist eine Erweiterung zu unserem Kontaktformular Tutorial.

Wer ein Kontaktformular auf seiner Webseite eingebaut hat und keinen Spam-Schutz integriert hat, kennt das Problem: Die Masse der Nachrichten, die ankommen, sind schlecht ausgefüllt und machen einfach keinen Sinn. Sie sind von so genannten Bots ausgefüllt und versendet.

Das sind meistens kleine Scripte, die sich durch das ganze Internet bewegen und solche Formulare suchen. Es wird dann meistens einfach Werbung verschickt. Sehr ärgerlich für den Webmaster wird es dann, wenn die erste echte Nachricht untergegangen ist, weil man sich denkt: “Ist doch eh nur Schrott”.

Die Entwicklung von Spam-Schutz für Formulare

Captcha

Abbildung 1: Herkömmliches Captcha

Irgendwann kamen die Entwickler auf die Idee, Formularen eine Art Passwort zu geben, welches zwar im Formular angezeigt wird, aber eben von Bots nicht gelesen werden kann. So entstanden die Captchas, die wie in Abbildung 1 oft ein schwer lesbares Bild anzeigen und man soll den Inhalt in das entsprechende Feld eingeben. Eine weitere Möglichkeit waren auch kleine Rechenaufgaben.

Allerdings hat es nicht besonders lange gedauert, bis die Bots auch diese Sachen ziemlich gut lesen und erkennen konnten. Ein Captcha in Form eines Bildes oder einer Rechenaufgabe einzubinden ist immer noch weit aus besser als nichts und kann die Masse der Bots davon abhalten das Formular abzusenden. Aber eben nicht alle.

Funfact:
Mit Captchas wurde / wird sogar richtig Geld verdient. Beim automatisierten Einscannen von Büchern kommt es oft vor, dass der innere Teil der Seite verschwommen und schlecht lesbar ist. Genau diese Abschnitte wurden oft als Captchas verwendet und jeder der so etwas ausgefüllt hat, hat quasi für die “Einscanner” gearbeitet.

Google reCAPCTHA: Jetzt wird es schwierig für die Bots

Ende 2014 kam Google mit einer neuen Möglichkeit: reCAPTCHA. Dabei muss beim Absenden des Formulars vom Nutzer kein unlesbarer Text mehr eingegeben werden, sondern lediglich eine Checkbox aktiviert werden.

Google reCAPTCHA

Abbildung 2: Google reCAPTCHA – Quelle: Google.com/reCAPTCHA

Durch das Einbinden eines zusätzlichen JavsScripts, überprüft Google anhand der IP-Adresse das Surf-Verhalten und die Mausbewegungen des Nutzers auf der Webseite. Ist sich Google unsicher, wird trotzdem noch eine kleine Aufgabe an den Nutzer ausgegeben (siehe Abbildung 3). Im Großen und Ganzen ist es von der Nutzererfahrung allerdings um Welten besser, als unlesbare Texte oder Rechenaufgaben.

Google reCAPTCHA Nachfrage

Abbildung 3: Wenn sich Google nicht ganz sicher ist, wird nochmal eine Aufgabe gestellt.

Tutorial: So bindet man reCAPTCHA in ein Kontaktformular ein

Dies ist die Erweiterung zu unserem Tutorial “Kontaktformular mit Bootstrap“.

Schritt 1: Anmeldung bei Google reCAPTCHA und Webseite registrieren

Um reCAPTCHA nutzen zu können, ist es notwendig sich bei diesem Google-Dienst zunächst zu registrieren: https://www.google.com/recaptcha/

Der Service ist natürlich wie beinahe alle Google Services kostenlos. Für die Registrierung wird lediglich ein Google Account benötigt, den wahrscheinlich jeder besitzen dürfte, der schon einmal eine Webseite veröffentlicht hat.

Nach der Anmeldung muss die Webseite registriert werden. Für jede neue Webseite, auf der reCAPTCHA genutzt werden möchte, muss diese Webseiten-Registrierung durchgeführt werden.

Webseite registrieren

Abbildung 4: Webseite bei reCAPTCHA registrieren

Im Feld “Label” wird einfach der Name der Webseite eingegeben. In dem Feld “Domains” wird die Domain eingegeben. Hier müssen auch Subdomains eingetragen werden, auf denen der Service genutzt werden möchte. Wenn die Checkbox “Benachrichtigungen” aktiviert ist, werden Nachrichten verschickt, sobald etwas nicht mehr funktioniert.

Schritt 2: Javascript einbinden

In der Übersicht der eingetragenen Webseiten, kann nun die Detail-Seite zur jeweiligen Webseite geöffnet werden. Klicke dazu einfach in der Liste auf den Namen der Webseite.

Nun muss zunächst das Javascript in die Seite eingebunden werden. Wichtig: Es muss vor dem schließenden <head>-Tag erfolgen:

...
     <script src='https://www.google.com/recaptcha/api.js'></script>
</head>
...

Schritt 3: reCAPTCHA in das Formular einbinden

Als nächstes muss folgendes HTML-Tag an die Stelle im Formular eingefügt werden, wo das reCAPTCHA erscheinen soll. Das kann zum Beispiel so aussehen:

<form method="POST" action="senden.php">
     ... <!-- Hier die Formularfelder -->
     <div class="g-recaptcha" data-sitekey="SITEKEY"></div>
     <button type="submit">Absenden</button>
</form>

Man sieht, dass das DIV mit der CSS-Klasse g-recaptcha dafür verantwortlich ist, das Captcha an der richtigen Stelle anzuzeigen. Wichtig ist, dass der richtige data-sitekey eingesetzt wird. Jede Webseite hat seinen eigenen Sitekey. Diesen findet man in der Detail-Seite der Webseite. Ersetzt “SITEKEY” einfach mit diesem.

Damit ist das Captcha eingebaut. Wer die Darstellung, etc. anpassen möchte, der sollte sich diese Dokumentation ansehen.

Schritt 4: Einbinden in unsere Formular-Kontrolle

Nun wollen wir natürlich nicht, dass das Formular abgesendet werden kann, wenn der User den Anti-Spam-Test nicht durchgeführt hat. Also erweitern wir unsere Formularkontrolle.

Wir müssen also von unserem reCaptcha Feedback erhalten, ob der Test ausgeführt wurde. Dafür legen wir eine neue Variable in unserer Formularkontrolle an:

var telefon = $('#telefon').val();
var nachricht = $('#nachricht').val();
var isHuman = grecaptcha.getResponse(); <!-- NEUE VARIABLE -->

Mit der Funktion getResponse() gibt uns das Google reCAPTCHA Feedback, ob der Test durchgeführt wurde. Ist der Test nicht durchgeführt worden oder fehlgeschlagen, ist der Inhalt dieser Variable leer. Deshalb können wir nun folgende if-Abfrage hinzufügen:

if(isHuman.length == 0) {
    formControl = false;
}

Somit haben wir nun auf der Client-Seite bereits überprüft, ob das Formular von einem echten Menschen oder einem Bot ausgefüllt wurde. Selbstverständlich sollte hier auch noch eine Fehlermeldung für den User ausgegeben werden. Wie das geht, steht im Tutorial Teil 1.

Wie bereits in unserem Kontakformular-Tutorial erwähnt, muss dieser Kontrolle auch nochmal auf dem Server stattfinden. Wichtig dabei ist deshalb, dass das Feedback von Google reCAPTCHA auch mit an das PHP-Script übergeben wird. Es muss also im AJAX-Call mitgegeben werden:

$.ajax({
    type: 'POST',
    url: 'php/absenden.php',
    data: { 
        vorname:vorname, 
        nachname:nachname, 
        email:email, 
        telefon:telefon, 
        nachricht:nachricht, 
        isHuman:isHuman 
    }
}).done(function(message) {
...

Schritt 5: Server-Seitige Formular-Kontrolle

Die Server-seitige Kontrolle findet in unserem PHP-Script statt. Zunächst prüfen wir, ob das reCAPTCHA überhaupt im Formular eingebunden war, als das Formular abgesendet wurde:

if(isset($_POST['isHuman'])) {
    $captcha = $_POST['isHuman'];
} else {
    die();
}

Ist also die Variable “isHuman” mitgesendet worden, speichern wir uns den Inhalt in eine neue Variable mit dem Name “captcha”.

Nun haben wir die Möglichkeit nochmal direkt bei Google nachzufragen, ob der Test denn wirklich erfolgreich war. Dies passiert über die reCAPTCHA-API wie folgt:

$ergebnis = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=DEIN_SECRET_KEY&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);

Wie man sieht, wird hier einfach der Rückgabe-Wert einer URL abgefragt. So funktionieren übrigens APIs. Beim Aufruf der URL müssen folgende Variablen mitgeliefert werden:

  • secret = Der Secret-Key. Diesen findest Du im Google reCAPTCHA Login auf der Detail-Seite Deiner Webseite
  • response = Der Inhalt aus der Variable $captcha
  • remoteip = Die IP-Adresse des Users

Das Ergebnis der API-Abfrage wird in der Variable $ergebnis gespeichert. Nun können wir das Ergebnis wie folgt prüfen:

if($ergebnis.success == false) {
    die(); <!-- Es handelt sich um einen Bot -->
}

Das war’s dann mit den Bots

Jetzt haben wir eine wirklich gute Anti-Spam-Funktion in unser Formular eingebaut und bekommen im besten Falle gar keine Spam-Nachricht mehr über unser Kontaktformular

Ich hoffe es wurde alles verständlich und übersichtlich erklärt. In den nächsten Tagen wird noch ein Video folgen, auf dem wieder alles per Screencast umgesetzt wird.

Du möchtest regelmäßig mit interessanten Neuigkeiten zum Thema "Twitter Bootstrap" versorgt werden? Trag Dich in den Bootstrapaholic Newsletter ein. Wir versenden keinen Spam! Du kannst Dich jederzeit austragen.

Dieser Beitrag wurde unter Bootstrap Tutorials abgelegt am von .

15 Gedanken zu „reCAPTCHA: Der Spam-Schutz für Dein Kontaktformular

  1. Pingback: Kontakformular mit Bootstrap und PHP – Download und Tutorial | Bootstrapaholic

  2. Marius

    Hallo und danke für das neue Tutorial!!!!
    Bei mir funktioniert das rechapta noch nicht ganz. Die php Datei wird anscheinend gar nicht aufgerufen bei mir. Kannst du dir mal mein Script anschauen?

    $(‘#kontaktformular’).submit(function() {
    var formControl = true;

    var frmGrpVorname = $(‘#frmGrpVorname’);
    var frmGrpNachname = $(‘#frmGrpNachname’);
    var frmGrpTelefon = $(‘#frmGrpTelefon’);
    var frmGrpEmail = $(‘#frmGrpEmail’);
    var frmGrpNachricht = $(‘#frmGrpNachricht’);

    frmGrpVorname.removeClass(‘has-error’);
    frmGrpNachname.removeClass(‘has-error’);
    frmGrpTelefon.removeClass(‘has-error’);
    frmGrpEmail.removeClass(‘has-error’);
    frmGrpNachricht.removeClass(‘has-error’);

    var vorname = $(‘#vorname’).val();
    var nachname = $(‘#nachname’).val();
    var telefon = $(‘#telefon’).val();
    var email = $(‘#email’).val();
    var nachricht = $(‘#nachricht’).val();
    var isHuman = grecaptcha.getResponse();

    if(vorname == ”) {
    formControl =false;
    frmGrpVorname.addClass(‘has-error’);
    }

    if(nachname == ”) {
    formControl =false;
    frmGrpNachname.addClass(‘has-error’);
    }

    if(email == ”) {
    formControl =false;
    frmGrpEmail.addClass(‘has-error’);
    }

    if(nachricht == ”) {
    formControl =false;
    frmGrpNachricht.addClass(‘has-error’);
    }

    if(isHuman.length == 0) {
    formControl = false;
    }

    if(formControl){
    alert(‘Nachricht abgeschickt’);

    $.ajax({
    type: ‘POST’,
    url: ‘../php/absenden.php’,
    data: { vorname:vorname, nachname:nachname, telefon:telefon, email:email, nachricht:nachricht, isHuman:isHuman }
    }).done(function(message){
    var erfolgsmeldung = $(‘#erfolgsmeldung’);
    erfolgsmeldung.html(message);
    erfolgsmeldung.addClass(‘alert’);
    erfolgsmeldung.addClass(‘alert-success’);
    });
    }

    return false;

    });

    Antworten
    1. Christoph Paterok Artikelautor

      Hmm eigentlich sieht alles ganz gut aus.

      Was mir nur auffällt: Die PHP-Datei, an die Du die Daten sendest müsste, so wie Du es jetzt gerade eingebunden hast, in einem übergeordneten Verzeichnis liegen. Ist das so?

      Also so ungefähr müsste es bei Dir gerade aussehen:
      – hauptverzeichnis
      – – php
      – – – absenden.php
      – – html
      – – – kontakformular.html

      Wenn es daran nicht liegt, kannst Du mir das gesamte Script gerne mal per E-Mail schicken, dann schau ich mir das morgen mal an.

      Antworten
  3. Marius

    Hallo!
    Muss in der php Datei nicht das “!” weg bei dem IF??

    if(!isset($_POST[‘isHuman’])) {
    $captcha = $_POST[‘isHuman’];
    } else {
    die();
    }

    Antworten
    1. Christoph Paterok Artikelautor

      Hi Marius :)

      sorry, dass ich Dir noch nicht auf Deine Mail geantwortet hatte.

      Du hast absolut recht! Danke für den Hinweis, ich werde das sofort hier ausbessern.

      Antworten
  4. Carlos030

    Hi, ich habe mir u.a. dein Tutorial angeschaut und leider funktioniert es bei mir nicht so recht.
    Kannst du mir vielleicht helfen?

    kontakt.html:

    Contact

    Deine Email

    Dein Kommentar

    kontakt.php:

    Antworten
  5. Uli

    Hallo zusammen,
    vielen Dank Christoph für das Tutorial bei youtube und die Erweiterung um reCaptcha 2 von Google.

    Vielleicht hat jemand eine Lösung für mich, ich bekomme es einfach nicht gebacken, nach dem absenden des Formulars auf eine Bestätigungsseite umzuleiten. Den von Christoph vorgenommenen Aufruf der Alert-Meldung habe ich in der html- und PHP-Datei auskommentiert. Bestätigungsmails werden versendet, das Forular bleibt gefüllt eine Weiterleitung über header('location:http://www.google.de');. Egal ob ich die Weiterleitung nach mail($empfaenger, $betreff, $text, implode("\r\n",$headers)); in der PHP-Datei aufrufe, oder nach Aufruf von Ajax in der html-Datei.

    Hat hier jemand einen Tipp? Dateien gerne per Mail, Formular ist hier: http://kontakt.andweb.de

    Grüße
    Uli

    Antworten
    1. Uli

      Lösung gefunden, Weiterleitung erfolgt in der index-Datei
      Anpassungen sind wie folgt vorzunehmen:


      if(formControl) {
      $.ajax({
      type: 'POST',
      url: 'php/absenden.php',
      data: { vorname:vorname, nachname:nachname, email:email, telefon:telefon, nachricht:nachricht, isHuman:isHuman }
      })
      .done(function(message) {
      window.location.href = 'bestaetigungsseite.html';
      });
      }

      Antworten
  6. jerome85

    Hi, erstmal vielen dank für dein erstes tutorial, und das hier mit dem captcha :-).
    hab alles soweit hinbekommen das es läuft, nur raffe ich das mit dem servierseitigen test nicht so wo und wie ich es einfüge?

    die php sieht bei mir so aus :

    <?php
    $firma = $_POST['firma'];
    $name = $_POST['name'];
    $straße = $_POST['straße'];
    $plz = $_POST['plz'];
    $telefon = $_POST['telefon'];
    $fax = $_POST['fax'];
    $email = $_POST['email'];
    $nachricht = $_POST['nachricht'];
    if(isset($_POST['isHuman'])) {
    $captcha = $_POST['isHuman'];
    } else {
    die();
    }
    $empfaenger = "info@carstyler-giessen.de"; //Hier die E-Mail
    $absendername = "Kontaktformular";
    $absendermail = $email;
    $betreff = "Neue Anfrage";
    $text = "Es ist eine neue Nachricht über das Kontaktformular eingetroffen.

    Firma: ".$firma."
    Name: ".$name."
    Anschrift: ".$straße."
    PLZ/Ort: ".$plz."
    Telefon: ".$telefon."
    Fax: ".$fax."
    E-mail: ".$email."
    Nachricht:
    ".$nachricht;
    mail($empfaenger, $betreff, $text, "From: $absendername “);

    echo(“Das Formular wurde erfolgreich versendet”);
    ?>

    Antworten
      1. jerome85

        Sorry ja der server-seitigen Test mit recaptcha wo man den secretkey eingeben muss, der rest funktioniert wunderbar.

        Dank deinem tutorial

        Antworten
          1. jerome85

            Ich hab mal es so eingefügt in die php, wenn ich das richtig verstanden habe.

            <?php
            $firma = $_POST['firma'];
            $name = $_POST['name'];
            $straße = $_POST['straße'];
            $plz = $_POST['plz'];
            $telefon = $_POST['telefon'];
            $fax = $_POST['fax'];
            $email = $_POST['email'];
            $nachricht = $_POST['nachricht'];
            if(isset($_POST['isHuman'])) {
            $captcha = $_POST['isHuman'];
            } else {
            die();
            }
            //Captcha check, seien Sie sicher das er wirklich kein Bot ist:)…
            $ergebnis = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=mein-secret-key&response=&quot;.$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
            if($ergebnis.success == false) {
            die();
            }
            $empfaenger = “info@juwelier-yildiz.de”; //Hier die E-Mail
            $absendername = “Kontaktformular”;
            $absendermail = $email;
            $betreff = “Neue Anfrage”;
            $text = “Es ist eine neue Nachricht ueber das Kontaktformular eingetroffen.

            Firma: “.$firma.”
            Name: “.$name.”
            Anschrift: “.$straße.”
            PLZ/Ort: “.$plz.”
            Telefon: “.$telefon.”
            Fax: “.$fax.”
            E-mail: “.$email.”
            Nachricht:
            “.$nachricht;
            mail($empfaenger, $betreff, $text, “From: $absendername “);

            echo(“Das Formular wurde erfolgreich versendet”);
            ?>

  7. Rudolf

    Hallo ,
    Christoph vielen Dank für das Tutorial bei youtube und hier. Da ich gerade meine Webseite neu gestalte passt das prima. Ich habe auch gleich alles bis auf reCAPTCHA erwendet. E-Mail mit allen Daten wird versendet. Prima. Nur .done(function(message) gibt keine Meldung.Die echo Meldung wird immer auf eine extra Site ausgegeben.
    Was mache ich falsch?
    Über eine Antwort wäre ich sehr dankbar.

    Formular.php:
    ————————
    if(formControl)
    {
    $.ajax
    ({

    type: ‘POST’,
    url: ‘../php/senden1.php’,
    data: {
    hf50rolle100:hf50rolle100,
    hf50rolle130:hf50rolle130,
    hf50qm100:hf50qm100,
    hf50qm130:hf50qm130,
    hf100rolle100:hf100rolle100,
    hf100rolle130:hf100rolle130,
    hf100qm100:hf100qm100,
    hf100qm130:hf100qm130,
    hf140rolle100:hf140rolle100,
    hf140rolle130:hf140rolle130,
    hf140qm100:hf140qm100,
    hf140qm130:hf140qm130,
    hammertacker:hammertacker,
    tacker:tacker,
    klammern:klammern,
    v2alochband:v2alochband,
    inlineRadioOptionen:inlineRadioOptionen,
    vorname:vorname,
    nachname:nachname,
    email:email,
    textfeld:textfeld,
    }

    })

    .done(function(message) {
    var erfolgsmeldung = $( ‘#erfolgsmeldung’ );
    erfolgsmeldung.html(message);
    erfolgsmeldung.addClass(‘alert’);
    erfolgsmeldung.addClass( ‘alert-success’ );

    });
    }
    return false;
    });
    >

    senden1.php :
    ———————-

    <?php
    $empfaenger = "anfrage@haider-abschirmtechnik.de"; //Hier die E-Mail
    $absendername = "Kontaktformular";
    $absendermail = $_POST['email'];
    $betreff = "Neue Anfrage";
    $text = "
    Vorname: ".$_POST['vorname']."\n
    Nachname: ".$_POST['nachname']."\n
    E-Mail: ".$_POST['email']."\n
    Nachricht: ".$_POST['textfeld']."\n
    Anrede: ".$_POST['inlineRadioOptionen']."\n
    v2alochband: ".$_POST['v2alochband']."\n
    klammern: ".$_POST['klammern']."\n
    tacker: ".$_POST['tacker'].";\n
    hf50rolle100cm: ".$_POST['hf50rolle100']."\n
    hf50rolle130cm: ".$_POST['hf50rolle130']."\n
    hf50qm100cm: ".$_POST['hf50qm100']."\n
    hf50qm130cm: ".$_POST['hf50qm130']."\n
    hf100rolle100cm: ".$_POST['hf100rolle100']."\n
    hf100rolle130cm: ".$_POST['hf100rolle130']."\n
    hf100qm100cm: ".$_POST['hf100qm100']."\n
    hf100qm130cm: ".$_POST['hf100qm130']."\n
    hf140rolle100cm: ".$_POST['hf140rolle100']."\n
    hf140rolle130cm: ".$_POST['hf140rolle130']."\n
    hf140qm100cm: ".$_POST['hf140qm100']."\n
    hf140qm130cm: ".$_POST['hf140qm130']."\n";

    mail($empfaenger, $betreff, $text, "From: $absendername “);

    echo(“Das Formular wurde erfolgreich versendet.”);
    ?>

    Besten Dank
    Rudolf

    Antworten
    1. Christoph Paterok Artikelautor

      Hi Rudolf, sorry für die verspätete Antwort. Kannst Du mir die Dateien bitte mal per E-Mail schicken? Dann kann ich mir das mal genauer anschauen.

      Antworten

Hinterlasse einen Kommentar zu jerome85 Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>