Skip to content

Commit

Permalink
Start working on reCAPTCHA v3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Mühl committed Nov 29, 2018
1 parent 58c6b1a commit 05ac27f
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 8 deletions.
10 changes: 9 additions & 1 deletion README.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## Contao reCAPTCHA Integration
Contao 4 Bundle that replaces the default Contao captcha with Google's invisible reCAPTCHA or reCAPTCHA 2.0.
A Contao 4 Bundle that replaces Contao's default captcha with the more robust [Google reCAPTCHA](https://www.google.com/recaptcha/intro/v3.html).

We support the following captchas:
- reCAPTCHA v2 Checkbox
- reCAPTCHA v2 Invisible
- reCAPTCHA v3 (currently work in progress)

### Installation
Either require `dieschittigs/contao-recaptcha` via composer or install the bundle from your Contao Manager.

#### Fallback
If either the private or public key is left empty, the captcha falls back to the default Contao captcha.
Expand Down
21 changes: 17 additions & 4 deletions src/Form/FormRecaptcha.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function __construct($arrAttributes = null)
$this->recaptchaType = Config::get('recaptchaType');
$this->publicKey = Config::get('recaptchaPublicKey');
$this->privateKey = Config::get('recaptchaPrivateKey');
$this->globalThreshold = Config::get('recaptcha3GlobalThreshold');

if ($this->useFallback()) {
$this->strTemplate = 'form_captcha';
Expand All @@ -40,9 +41,9 @@ public function validate()
try {
$response = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : false;
if ($response === false) throw new \Exception;

$curl = curl_init('https://www.google.com/recaptcha/api/siteverify');

curl_setopt($curl, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
Expand All @@ -54,15 +55,27 @@ public function validate()

$response = curl_exec($curl);
if ($response === false) throw new \Exception; // Request error

$parsed = json_decode($response, true);
if (!$parsed['success']) {
if (in_array('invalid-input-secret', $parsed['error-codes'])) {
\System::log('Google reCAPTCHA private key is invalid.', __METHOD__, TL_CONFIGURATION);
}

throw new \Exception;
}

if ($this->recaptchaType === 'recaptcha3') {
$score = $parsed['score'];

// Use this field's threshold, otherwise use the default
$threshold = $this->recaptcha3_threshold ? $this->recaptcha3_threshold : $this->globalThreshold;
if (!$threshold) $threshold = 0;

if ($score < $threshold) {
throw new \Exception;
}
}
} catch (\Exception $e) {
$this->class = 'error';
$this->addError($GLOBALS['TL_LANG']['ERR']['recaptcha']);
Expand Down
8 changes: 8 additions & 0 deletions src/Resources/contao/dca/tl_form_field.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

$GLOBALS['TL_DCA']['tl_form_field']['fields']['recaptcha3_threshold'] = [
'label' => &$GLOBALS['TL_LANG']['tl_form_field']['recaptcha3_threshold'],
'inputType' => 'text',
'sql' => "varchar(8) unsigned NOT NULL default '0'",
'eval' => ['tl_class' => 'w50']
];
14 changes: 11 additions & 3 deletions src/Resources/contao/dca/tl_settings.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
'options_callback' => function ()
{
return [
'invisible' => 'Invisible reCAPTCHA',
'recaptcha2' => 'reCAPTCHA v2'
'invisible' => 'reCAPTCHA v2: Invisible',
'recaptcha2' => 'reCAPTCHA v2: Checkbox',
'recaptcha3' => 'reCAPTCHA v3',
];
},
'eval' => ['chosen' => true]
'eval' => ['chosen' => true, 'submitOnChange' => true]
];

$GLOBALS['TL_DCA']['tl_settings']['fields']['recaptchaPublicKey'] = [
Expand All @@ -25,4 +26,11 @@
'eval' => ['tl_class' => 'w50']
];

$GLOBALS['TL_DCA']['tl_settings']['fields']['recaptcha3GlobalThreshold'] = [
'label' => &$GLOBALS['TL_LANG']['tl_settings']['recaptcha3GlobalThreshold'],
'inputType' => 'text',
'default' => '0.5',
'eval' => ['tl_class' => 'w50']
];

$GLOBALS['TL_DCA']['tl_settings']['palettes'] = str_replace('{files_legend', '{recaptcha_legend},recaptchaType,recaptchaPublicKey,recaptchaPrivateKey;{files_legend', $GLOBALS['TL_DCA']['tl_settings']['palettes']);
2 changes: 2 additions & 0 deletions src/Resources/contao/languages/de/tl_settings.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
$GLOBALS['TL_LANG']['tl_settings']['recaptchaPublicKey'][1] = "Der Schlüssel, der im HTML-Code der Seite ausgegeben wird.";
$GLOBALS['TL_LANG']['tl_settings']['recaptchaPrivateKey'][0] = "Geheimer Schlüssel";
$GLOBALS['TL_LANG']['tl_settings']['recaptchaPrivateKey'][1] = "Der Schlüssel, der für die Kommunikation zwischen Contao und Google verwendet wird.";
$GLOBALS['TL_LANG']['tl_settings']['recaptcha3GlobalThreshold'][0] = "Score-Minimum";
$GLOBALS['TL_LANG']['tl_settings']['recaptcha3GlobalThreshold'][1] = "reCAPTCHA v3 bewertet Nutzeraktionen mit einem Wert zwischen 0 und 1, wobei 1 für einen sehr wahrscheinlich guten Nutzer und 0 für einen Bot steht. Wenn ein globales Minimum gesetzt wird, muss die Bewertung von Google mindestens diesen Wert erreichen, damit das Captcha als Erfolg gezählt wird.";

$GLOBALS['TL_LANG']['tl_settings']['recaptcha_legend'] = "Sicherheit: Google reCAPTCHA";
2 changes: 2 additions & 0 deletions src/Resources/contao/languages/en/tl_settings.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
$GLOBALS['TL_LANG']['tl_settings']['recaptchaPublicKey'][1] = "The key that's getting served to your users.";
$GLOBALS['TL_LANG']['tl_settings']['recaptchaPrivateKey'][0] = "Secret key";
$GLOBALS['TL_LANG']['tl_settings']['recaptchaPrivateKey'][1] = "They key that's used for communication between Contao and Google.";
$GLOBALS['TL_LANG']['tl_settings']['recaptcha3GlobalThreshold'][0] = "Global score threshold";
$GLOBALS['TL_LANG']['tl_settings']['recaptcha3GlobalThreshold'][1] = "reCAPTCHA v3 returns a score, based on which you can decide if a user is likely a bot or a human. A score of 1 most likely resembles a human, a score of 0 is most likely a bot. Any captcha request made has to be above this score to be considered safe.";

$GLOBALS['TL_LANG']['tl_settings']['recaptcha_legend'] = "Security: Google reCAPTCHA";

0 comments on commit 05ac27f

Please sign in to comment.