For my latest full-stack web app I'm creating a registration page to create a login for the site and I'm using ReCAPTCHA. I've written both the client and server side scripts, but the browser is returning a 403 and "Error verifying captcha: Unexpected non-whitespace character after JSON at position 39". I've tried console logging the data but nothing comes up. I've included both my client and server side code. Please let me know what I missed.
Register.html:
<!DOCTYPE html>
<html>
<head>
<title>Easy Estimator Registration</title>
<link rel="stylesheet" href="ee.css">
<link rel="preconnect" href="https://www.google.com">
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
<script src="https://www.google.com/recaptcha/api.js" async defer>
</script>
</head>
<body>
<header>
<h1>Easy Estimator Registration</h1>
</header>
<form id="register" name="register" method="post" action="load.php">
<fieldset>
<legend>Register</legend>
<p>Complete all fields below to start an account and begin using Easy Estimator.</p>
<ul>
<li><label for="email">Email:</label></li>
<li><input id="email" name="email"/></li>
<li><label for="fullname">Name: </label></li>
<li><input id="fullname" name="fullname"/></li>
<li><label for="username">Username:</label></li>
<li><input id="username" name="username"/></li>
<li><label for="password">Password:</label></li>
<li><input id="password" name="password"/></li>
<li><label for="confirmpassword">Confirm Password:</label></li>
<li><input id="confirmpassword" name="confirmpassword"/></li>
<li><br/></li>
<li><div class="g-recaptcha" data-sitekey="SITEKEY"></div></li>
</ul>
<ul id="buttons">
<li><input id="submit" type="submit" value="Submit"></li>
<li><input type="reset" value="Reset"></li>
</ul>
<ul id="links">
<li><a href="login.html">Login</a></li>
</ul>
<div id="alertMsg"></div>
</fieldset>
</form>
<script>
document.getElementById('register').addEventListener('submit', function (event) {
event.preventDefault();
registerUser();
});
// Function to handle the form submission and ReCAPTCHA verification
async function registerUser() {
const form = document.getElementById('register');
const formData = new FormData(form);
console.log(formData);
const captchaResponse = grecaptcha.getResponse();
formData.append('captchaResponse', captchaResponse);
try {
const response = await fetch('/easyestimator/load.php', {
method: 'POST',
headers: {
'Accept': 'application/json'
},
body: formData,
});
const data = await response.json();
console.log(data);
if (data.success) {
// Captcha verification successful, proceed with user registration
// Implement your user registration logic here
form.submit(); // Submit the form to complete the registration
} else {
// Captcha verification failed, display an error message to the user
console.error('Captcha verification failed:', data.error);
alert('Captcha verification failed. Please try again.');
}
} catch (error) {
console.error('Error verifying captcha:', error.message);
alert('An error occurred while verifying captcha. Please try again later.');
}
}
</script>
<footer>
<p>Copyright 2023 Eric M. Pastore. All Rights Reserved.</p>
</footer>
</body>
</html>
load.php:
<?php
//capture info from form
$email = $_POST["email"];
$fullname = $_POST["fullname"];
$username = $_POST["username"];
$password = $_POST["password"];
$signup = date("Y-m-d");
// open connection to ee server
$mysqli = new mysqli("localhost", "#########","##########","###########");
// verify if connection was successful
if ($mysqli -> connect_errno)
{
echo "Failed to connect to MySQL: ".$mysqli -> connect_error;
exit();
}
// load values from POST superglobal into logins table
// **ensure passwords are hashed on load
$load_query = $mysqli -> prepare("INSERT INTO logins(email,full_name,user_name,password,signup_date) VALUES(?,?,?,?,?)");
$load_query -> bind_param("sssss",$email,$fullname,$username,$password,$signup);
$load_query -> execute();
$load_query -> close();
$mysqli -> close();
// **send confirmation email of registration details
$msg = "Thank you for registering for Easy Estimator on $signup.\n";
//mail($email,"Easy Estimator Registration",$msg);
// implement Google Captcha
if($_SERVER['REQUEST_METHOD']==='POST')
{
$recaptchaSecretKey = 'SECRET_KEY';
if(!isset($_POST['captchaResponse']))
{
http_response_code(400);
echo json_encode(array('error' => 'Captcha response missing',
'post variable' => $_POST['captchaResponse']));
exit();
}
$captchaResponse = $_POST['captchaResponse'];
$verificationResponse = verifyRecaptcha($recaptchaSecretKey,$captchaResponse);
if ($verificationResponse['success'])
{
//add registration code
http_response_code(200);
echo json_encode(array('success' => true, 'message' => 'Captcha verified successfully'));
} else
{
http_response_code(403);
echo json_encode(array('error' => 'Captcha verification failed' ));
}
}
function verifyRecaptcha($secretKey,$response)
{
$url = 'https://www.google.com/recaptcha/api/siteverify';
$data = array('secret'=>$secretKey, 'response'=>$response,);
$options = array
(
'http' => array
(
'header' => 'Content-type: application/x-www-form-urlencoded',
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url,false,$context);
if($result === false)
{
return array('success' => false,
'error' => 'Error verifying captcha'
);
}
return json_decode($result,true);
}
// **direct to registration confirmation page
// **registration confirmation must confirm load and direct to login
echo "<html>";
echo "<head><title>Registration Complete</title></head>";
echo "<body>";
echo "<h1>Thanks for registering, $fullname. Today's date is $signup. Click login to log in to Easy Estimator.</h1>";
echo "</body>";
echo "</html>";
?>
The script is supposed to verify the user, load the data from the form into the logins table, and then send an email. I verified that the email function and the load function works. Now it's only the CAPTCHA that refuses to work.