Unable to get RECAPTCHA response properly

1 week ago 9
ARTICLE AD BOX

I'm trying to get a RECAPTCHA v2 request + response in my web project but so far I've got a lengthy g-recaptcha-response in my URL when I trigger the captcha action in my project. I'll provide the code below:

HTML:

<form id="captchaForm"> <div class="g-recaptcha" data-sitekey="my_site_key"></div> <button id="submitCaptcha" class="btn btn-sm w-100 fw-bold fs-5" type="submit"> Submit </button> </form>

validate.captcha.ts:

class ValidateCaptcha { private targetElement: string constructor(element: string) { this.targetElement = element; this.validate(element); } private validate(_element: string): void { try { const form = document.querySelector("#captchaForm") as HTMLFormElement; if (!form) { console.error("Form not found"); return; } form.addEventListener("submit", async (event: Event) => { event.preventDefault(); // Prevent form submission // Verify reCAPTCHA response const recaptchaResponse = grecaptcha.getResponse(); if (!recaptchaResponse) { console.error("Please complete the reCAPTCHA"); return; } try { const response = await fetch("../php/captcha_verify.php", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: new URLSearchParams({ "captcha_submit": "true", "g-recaptcha-response": recaptchaResponse }) }); if (response) { const result = await response.json(); if (result.success) { console.log("CAPTCHA SUCCESS!"); } else { grecaptcha.reset(); console.error("CAPTCHA verification failed"); } } else { console.error("Unable to fetch" + response); } } catch (error: unknown) { console.error("Verification error:", error); grecaptcha.reset(); } }); } catch (error: unknown) { console.error("Validation setup error:", error); } } } export default ValidateCaptcha;

captcha_verify.php:

<?php namespace App\Security; require_once dirname(path: __FILE__) . "../../../vendor/autoload.php"; use Dotenv\Dotenv; use GuzzleHttp\Client; use Exception; use InvalidArgumentException; class CaptchaVerifier { private string $buttonName; private string $secretKey; private string $verifyUrl = "https://www.google.com/recaptcha/api/siteverify"; private Client $httpClient; public function __construct(string $secretKey, string $buttonName = "captcha_submit") { $this->buttonName = $buttonName; $this->secretKey = $this->validateSecretKey(secretKey: $secretKey); $this->httpClient = new Client(); } private function validateSecretKey(string $secretKey): string { if (empty($secretKey) || strlen(string: $secretKey) < 10) { throw new InvalidArgumentException(message: "Invalid reCAPTCHA secret key"); } return $secretKey; } # Actual verifying happens here public function verify(string $recaptchaResponse): bool { if (empty($recaptchaResponse)) { return false; } try { # query for siteverify with secret key $verifyResponse = $this->httpClient->post(uri: $this->verifyUrl, options: [ "form_params" => [ "secret" => $this->secretKey, "response" => $recaptchaResponse ] ]); $responseBody = json_decode(json: $verifyResponse->getBody()->getContents(), associative: false); return $responseBody->success ?? false; } catch (Exception $e) { error_log(message: "reCAPTCHA verification failed: " . $e->getMessage()); return false; } } public function handleSubmission(array $formData): bool { if (!isset($formData[$this->buttonName])) { return false; } $recaptchaResponse = $formData["g-recaptcha-response"] ?? ""; return $this->verify(recaptchaResponse: $recaptchaResponse); } } class FormProcessor { private CaptchaVerifier $captchaVerifier; public function __construct() { $dotenv = Dotenv::createImmutable(paths: __DIR__ . "/../../"); $dotenv->load(); # Load secret key from environment variable $secret_key = $_ENV["RECAPTCHA_SECRET"]; try { if (!isset($secret_key)) { throw new InvalidArgumentException(message: "RECAPTCHA_SECRET_KEY is not set in the environment."); } else { $this->captchaVerifier = new CaptchaVerifier(secretKey: $_ENV["RECAPTCHA_SECRET"]); } } catch (Exception $error) { throw new Exception(message: "Unable to verify captcha: " . $error->getMessage()); } } public function processForm(): void { header(header: "Content-Type: application/json"); # Validate form submission via posting through a form element if ($_SERVER["REQUEST_METHOD"] !== "POST") { http_response_code(response_code: 405); echo json_encode(value: [ "success" => false, "message" => "Method Not Allowed" ]); exit; } # Validate form submission from front-end if (!isset($_POST["captcha_submit"])) { http_response_code(response_code: 400); echo json_encode(value: [ "success" => false, "message" => "Invalid submission" ]); exit; } $verificationResult = $this->captchaVerifier->handleSubmission(formData: $_POST); if ($verificationResult) { echo json_encode(value: [ "success" => true, "message" => "Captcha verified successfully", "nextAction" => "proceed" ]); } else { http_response_code(response_code: 401); echo json_encode(value: [ "success" => false, "message" => "Captcha verification failed", "action" => "retry" ]); } exit; } } $form = new FormProcessor(); $form->processForm();

I use/instantiate this ValidateCaptcha class in one of my web component as:

private static watchCaptcha() { if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", () => { WorkPage.initCaptcha(); }); } else { WorkPage.initCaptcha(); } } private static initCaptcha() { const captchaForm = document.querySelector("#captchaForm") as HTMLFormElement; if (captchaForm) { try { new ValidateCaptcha("captchaForm"); console.log("Captcha validator initialized"); } catch (error: unknown) { console.error("Unable to submit captcha:", error); } } else { console.error("Captcha form not found in DOM"); } } connectedCallback(): void { WorkPage.watchCaptcha(); }

I'm unable to get any concrete output whether this is viable or not... What I get instead is a lengthy URL of the g-recaptcha-response output:

g-recaptcha-response Output

Read Entire Article