hCaptcha Integration

This commit is contained in:
2024-04-23 14:05:29 +02:00
parent aea20b7a10
commit 51ee723dcb
22 changed files with 275 additions and 145 deletions

View File

@@ -0,0 +1,64 @@
<?php
namespace Core\Objects\Captcha;
use Core\Objects\ApiObject;
abstract class CaptchaProvider extends ApiObject {
const NONE = "none";
const RECAPTCHA = "recaptcha";
const HCAPTCHA = "hcaptcha";
const PROVIDERS = [self::NONE, self::RECAPTCHA, self::HCAPTCHA];
private string $siteKey;
private string $secretKey;
protected string $error;
public function __construct(string $siteKey, string $secretKey) {
$this->siteKey = $siteKey;
$this->secretKey = $secretKey;
$this->error = "";
}
public function getSiteKey(): string {
return $this->siteKey;
}
public function getError(): string {
return $this->error;
}
public static function isValid(string $type): bool {
return in_array($type, [self::RECAPTCHA, self::HCAPTCHA]);
}
public abstract function verify(string $captcha, string $action): bool;
public abstract function getName(): string;
public function jsonSerialize(): array {
return [
"name" => $this->getName(),
"siteKey" => $this->getSiteKey(),
];
}
protected function performVerifyRequest(string $url, string $captcha) {
$params = [
"secret" => $this->secretKey,
"response" => $captcha
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = @json_decode(curl_exec($ch), true);
curl_close($ch);
return $response;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Core\Objects\Captcha;
class GoogleRecaptchaProvider extends CaptchaProvider {
public function __construct(string $siteKey, string $secretKey) {
parent::__construct($siteKey, $secretKey);
}
public function verify(string $captcha, string $action): bool {
$url = "https://www.google.com/recaptcha/api/siteverify";
$success = false;
$response = $this->performVerifyRequest($url, $captcha);
$this->error = "Could not verify captcha: Invalid response from Google received.";
if ($response) {
$success = $response["success"];
if (!$success) {
$this->error = "Could not verify captcha: " . implode(";", $response["error-codes"]);
} else {
$score = $response["score"];
if ($action !== $response["action"]) {
$success = false;
$this->error = "Could not verify captcha: Action does not match";
} else if ($score < 0.7) {
$success = false;
$this->error = "Could not verify captcha: Google ReCaptcha Score < 0.7 (Your score: $score), you are likely a bot";
} else {
$success = true;
$this->error = "";
}
}
}
return $success;
}
public function getName(): string {
return CaptchaProvider::RECAPTCHA;
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Core\Objects\Captcha;
class HCaptchaProvider extends CaptchaProvider {
public function __construct(string $siteKey, string $secretKey) {
parent::__construct($siteKey, $secretKey);
}
public function verify(string $captcha, string $action): bool {
$success = true;
$url = "https://api.hcaptcha.com/siteverify";
$response = $this->performVerifyRequest($url, $captcha);
$this->error = "Could not verify captcha: Invalid response from hCaptcha received.";
if ($response) {
$success = $response["success"];
if (!$success) {
$this->error = "Captcha verification failed.";
}
}
return $success;
}
public function getName(): string {
return CaptchaProvider::HCAPTCHA;
}
}