{"id":1427,"date":"2020-07-26T21:41:17","date_gmt":"2020-07-26T19:41:17","guid":{"rendered":"https:\/\/hitco.at\/blog\/?p=1427"},"modified":"2021-10-10T17:41:49","modified_gmt":"2021-10-10T15:41:49","slug":"web-formulare-google-recaptcha-v3","status":"publish","type":"post","link":"https:\/\/hitco.at\/blog\/web-formulare-google-recaptcha-v3\/","title":{"rendered":"Web-Formulare mit Google reCAPTCHA v3 absichern"},"content":{"rendered":"\n<p>Googles reCAPTCHA v3 sichert Eingabeformulare gegen eine durch Bots automatisierte Nutzung &#8222;unsichtbar&#8220; ab. Mehr hierzu in der <a href=\"https:\/\/www.google.com\/recaptcha\/intro\/v3.html\" target=\"_blank\" rel=\"noreferrer noopener\">Anleitung von Google. <\/a><\/p>\n\n\n\n<p>Der Beispiel-Code zum Integrieren wollte bei mir nicht gleich auf Anhieb gelingen, daher diese &#8222;Notiz an mich selbst&#8220; in Form eines Blog-Beitrages, wie die erfolgreiche Vorgehensweise funktioniert:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>F\u00fcr die betreffende WebSite in der <a rel=\"noreferrer noopener\" href=\"https:\/\/www.google.com\/recaptcha\/admin\" target=\"_blank\">Admin-Console von Google<\/a> die n\u00f6tigen Eintr\u00e4ge vornehmen, also reCAPTCHA v3 Eintrag anlegen, man erh\u00e4lt einen Website-Schl\u00fcssel und einen geheimen Schl\u00fcssel.<\/li><li>Der Website-Schl\u00fcssel wird im JavaScript-Code der Website (somit im Quellcode sichtbar) an zwei Stellen ben\u00f6tigt werden. Den geheimen Schl\u00fcssel hingegen ben\u00f6tigen wir nur im PHP-Backend-Code.<\/li><li>An jenen stellen, an denen ich <code>$$YourGoogleWebSiteKey<\/code> bzw. <code>$$YourGoogleSecretKey<\/code> als Platzhalter hier verwende, sind die pers\u00f6nlichen Keys die in der Google Admin-Console angezeigt werden zu verwenden.<\/li><li>In der Website auf der sich das Formular befindet, in der <code>&lt;head&gt;<\/code> Section das Script einf\u00fcgen. <\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script src=\"https:\/\/www.google.com\/recaptcha\/api.js?render=$$YourGoogleWebSiteKey\"&gt;&lt;\/script&gt;\n<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Im <code>&lt;body&gt;<\/code> unterhalb des Formular-Ende-Tags <code>&lt;\/form&gt;<\/code> folgendes Script einf\u00fcgen:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\n  function RenewCaptcha() {\n    grecaptcha.ready(function() {\n      grecaptcha.execute('$$YourGoogleWebSiteKey', {action: 'submit'}).then(function(token) {\n        console.log(\"Set Captcha Token: \" + token);\n        document.getElementById(\"captcha\").value = token;\n      });\n    });\t\t\t\t\t\n  }\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Und bei den Formularfeldern, z.B. vor dem Submit-Button folgendes versteckte Feld einf\u00fcgen:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;input type=\"hidden\" id=\"captcha\" name=\"captcha\"\/&gt;<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Die Funktion &#8222;RenewCaptcha()&#8220; generiert den Code und f\u00fcgt ihn ins versteckte Feld ein. Damit diese getriggert wird &#8211; m\u00f6glichst kurz vor dem eigentlichen versenden &#8211; hinterlegen wir den Aufruf im Submit-Button als OnMouseEnter Event:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;button type=\"submit\" OnMouseEnter=\"RenewCaptcha()\"&gt;Nachricht senden&lt;\/button&gt;<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Ob die \u00c4nderungen am Formular funktioniert haben erkennt man nun bereits, indem in der F12-Konsole des Browsers eine Log-Zeile <code>\"Set Captcha Token: ......\"<\/code> generiert werden muss, sobald man sich mit der Maus \u00fcber den Submit-Button bewegt. <\/li><li>Hinweis: Der ReCAPTCHA Code ist nur ca. 2 Minuten g\u00fcltig, daher ist ein Aufruf der <code>RenewCaptcha()<\/code> Funktion direkt beim Laden des Formulars nicht ausreichend &#8211; der Anwender k\u00f6nnte l\u00e4ngere Zeit brauchen, um das Formular zu bef\u00fcllen. Umgekehrt hat bei mir das Hinterlegen im OnClick-Event nicht geklappt, da das Formular dann bereits submittet wird, noch bevor die Aktualisierung des Captcha-Codes erfolgt<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Das PHP-Backend &#8211; basierend auf einem <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/PHPMailer\/PHPMailer\" target=\"_blank\">PHPMailer <\/a>&#8211; ist wie folgt zu erg\u00e4nzen:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>if(!isset($_POST&#91;'captcha'])){\n  # Google Captcha V3 muss mit \u00fcbergeben werden\n  $err = true;\n  $errortext .= \"Die Captcha V3 Pr\u00fcfung ist leer, Sie wurden als Roboter identifiziert!&lt;br\/&gt;\\n\";\n} else {\n  $captcha = $_POST&#91;'captcha'];\n  $secretKey = \"$$YourGoogleSecretKey\";\n  $ip = $_SERVER&#91;'REMOTE_ADDR'];\n  $url =  'https:\/\/www.google.com\/recaptcha\/api\/siteverify?secret=' . urlencode($secretKey) .  '&amp;response=' . urlencode($captcha);\n  $response = file_get_contents($url);\n  $responseKeys = json_decode($response,true);\n  if(!$responseKeys&#91;\"success\"]) {\n    $err = true;\n    $errortext .= \"Die Captcha V3 Pr\u00fcfung wurde nicht bestanden, Sie wurden als Roboter identifiziert!&lt;br\/&gt;\\n\";\t\t\t\n  }\n}\t<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Das eigentliche Versenden des Formulars bindet man dann an eine Pr\u00fcfung der Variable <code>$err<\/code><\/li><\/ul>\n\n\n\n<p>Mein fertiges Beispiel ist unter <a rel=\"noreferrer noopener\" href=\"https:\/\/hitco.at\/kontaktformular-demo\/\" target=\"_blank\">https:\/\/hitco.at\/kontaktformular-demo<\/a><a href=\"https:\/\/hitco.at\/kontaktformular-demo\/\" target=\"_blank\" rel=\"noreferrer noopener\">\/<\/a> zu finden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Googles reCAPTCHA v3 sichert Eingabeformulare gegen eine durch Bots automatisierte Nutzung &#8222;unsichtbar&#8220; ab. Mehr hierzu in der Anleitung von Google. Der Beispiel-Code zum Integrieren wollte bei mir nicht gleich auf Anhieb gelingen, daher diese &#8222;Notiz an mich selbst&#8220; in Form eines Blog-Beitrages, wie die erfolgreiche Vorgehensweise funktioniert: F\u00fcr die betreffende WebSite in der Admin-Console von Google die n\u00f6tigen Eintr\u00e4ge vornehmen,&#8230; <\/p>\n","protected":false},"author":1,"featured_media":1432,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[3],"tags":[492,491,489,490],"class_list":["post-1427","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-it","tag-formular","tag-phpmailer","tag-recaptcha","tag-recaptcha-v3"],"_links":{"self":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts\/1427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/comments?post=1427"}],"version-history":[{"count":11,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts\/1427\/revisions"}],"predecessor-version":[{"id":1737,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts\/1427\/revisions\/1737"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/media\/1432"}],"wp:attachment":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/media?parent=1427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/categories?post=1427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/tags?post=1427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}