missing-input-response | Invisible reCaptcha - php

So, I'm trying to implement to some website the brand new Invisible reCaptcha by Google.
I am following the steps exactly but it continously gives me missing-input-reponse error.
HTML Code:
<form id="subscribe-form" class="form-inline" action="phpScripts/subscribe/subscribeHandler.php" method="post">
<div class="input-group">
<input type="email" name="email" class="form-control" size="50" placeholder="Email Address" required>
<div class="input-group-btn">
<button class="g-recaptcha btn btn-danger" data-sitekey="6LfoNhkUAAAAAEcQFx8vGHZKHXsZ_q0j2KDnmU9M" data-callback="submitForm">Subscribe</button>
</div>
</div>
</form>
PHP Code:
<?php
include 'databaseConnection.php';
if($_POST){
$secret = "MY SECRET KEY";
$captcha= $_POST['g-recaptcha-response'];
$ip = $_SERVER['REMOTE_ADDR'];
$url= file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$captcha&remoteip=$ip");
print_r($url);
$decodedResponse = json_decode($url, TRUE);
if($decodedResponse['success'] == 1){//code here}
So, I'm thinking that my $captcha variable cannot "catch" nothing from the POST of g-recaptcha-response. But why, this is exactly how Google says and exactly as the old reCaptcha v2.
Aswell, i have included <script src='https://www.google.com/recaptcha/api.js'></script>

I was facing the same problem for several hours, until I finally understood the logic behind this "invisible-captcha" !
the reason you don't get a response is simply because there is an empty textarea element with an id and name of g-recaptcha-response
this textarea only populates with the response string after the challenge has been completed (which happens normally in the usual recaptcha), but for "invisible-captcha" you must explicitly call grecaptcha.execute(); with your "submit" button, after which the textarea is populated, and your form is automatically submitted (assuming you have bound the submission with your callback function).
In my case, I already have php handling the form and recaptcha validation, so I decided to stick with the old "checkbox" version (at least until it gets improved), because I realized it will be really annoying to change everything (form submission logic, button action and JavaScript code) just to hide a checkbox! especially that both methods are nearly the same !

The issue could be that you're tying the functionality to a button possibly.
Try implementing the code they give you when creating your keys:
<form id="subscribe-form" class="form-inline" action="phpScripts/subscribe/subscribeHandler.php" method="post">
<div class="input-group">
<input type="email" name="email" class="form-control" size="50" placeholder="Email Address" required>
<div class="g-recaptcha" data-sitekey="{keyhere}"></div>
<div class="input-group-btn">
<button class="btn btn-danger" data-sitekey=" data-callback="submitForm">Subscribe</button>
</div>
</div>
</form>
For the PHP logic validation:
if ( $_POST['g-recaptcha-response'] ) {
$secret = '{keyhere}';
$response = file_get_contents( "https://www.google.com/recaptcha/api/siteverify?secret=" . $secret . "&response=" . $_POST['g-recaptcha-response'] . "&remoteip=" . $_SERVER['REMOTE_ADDR'] );
$response = json_decode( $response );
if ( ! $response->success ) {
//return error
}
//code logic below
}
The div code provided when creating the keys should properly generate all of the HTML from their end to be able to processed by your PHP validation when submitting your form.

Here is a solution.
Client Side
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>reCaptcha</title>
<!--api link-->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<!--call back function-->
<script>
function onSubmit(token) {
document.getElementById('reCaptchaForm').submit();
}
</script>
</head>
<body>
<div class="container">
<form id="reCaptchaForm" action="signup.php" method="POST">
<input type="text" placeholder="type anything">
<!--Invisible reCaptcha configuration-->
<button class="g-recaptcha" data-sitekey="<your site key>" data-callback='onSubmit'>Submit</button>
<br/>
</form>
</div>
</body>
</html>
Server Side validation: Create a signup.php file
<?php
//only run when form is submitted
if(isset($_POST['g-recaptcha-response'])) {
$secretKey = '<your secret key>';
$response = $_POST['g-recaptcha-response'];
$remoteIp = $_SERVER['REMOTE_ADDR'];
$reCaptchaValidationUrl = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secretKey&response=$response&remoteip=$remoteIp");
$result = json_decode($reCaptchaValidationUrl, TRUE);
//get response along side with all results
print_r($result);
if($result['success'] == 1) {
//True - What happens when user is verified
$userMessage = '<div>Success: you\'ve made it :)</div>';
} else {
//False - What happens when user is not verified
$userMessage = '<div>Fail: please try again :(</div>';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>reCAPTCHA Response</title>
</head>
<body>
<?php
if(!empty($userMessage)) {
echo $userMessage;
}
?>
</body>
</html>

Use grecaptcha.reset() to reset the recaptcha after each execution and all should work just fine. Follow this link for more info on grecaptcha.reset().

Related

Trouble with reCAPTCHA v3 verify score

Trying to implement a recaptcha on my Contact form for my website and I'm having trouble getting anything to go through unless I set the score to 0.0. Even 0.1 kicks it over to spam. There are so many examples of how to implement, and I've tried several of them but not had any luck (as several are for different versions too, which makes it hard for us noobs).
In any event, here is a stripped down version of the form html page I'm trying to use:
<head>
<script src='https://www.google.com/recaptcha/api.js?render=KEY'></script>
</head>
<body>
<form name="contactform" action="send_form_email.php" method="post">
<div class="input-group">
<span class="input-group-label">Name</span>
<input name="realname" class="input-group-field" type="text" value="Your Name Here" maxlength="50" onFocus="this.value=''">
</div>
<div class="input-group">
<span class="input-group-label">Email</span>
<input name="email" class="input-group-field" type="email" value="Your E-Mail Here" maxlength="50" onFocus="this.value=''">
</div>
<div class="input-group">
<span class="input-group-label">Message</span>
<textarea name="message" rows="10"></textarea>
</div>
<input type="Submit" class="button" value="SEND"><input type="Reset" class="button" value="RESET">
</form>
<script>
$(function(){ //wait for document ready
grecaptcha.ready(function() {
grecaptcha.execute('KEY', {action: 'contactUs'}).then(function(token) {
// Verify the token on the server.
});
});
});
</script>
</body>
So then I have a PHP form called send_form_email.php that I'm using to take care of all the hard work:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Build POST request:
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = 'SECRET_KEY';
$recaptcha_response = $_POST['g-recaptcha-response'];
// Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
$recaptcha = json_decode($recaptcha);
// Take action based on the score returned:
if ($recaptcha->score >= 0.0) {
// This is just where I take care of formatting the email and sending it to me, which is working just fine... well while the score is set to 0.0
}
} else {
// otherwise, let the spammer think that they got their message through
header('Location: success.htm');
exit();
}
}
?>
So this is where I run into my issue. In the code above I have it set to 0.0 and that is the ONLY way right now emails come through at all. But of course this lets through spam or real messages because it's basically off. As I said, if I set it to even 0.1 it isn't passing the score check and is never sending the email. I'm sure it's something simple that I'm missing or I'm not passing the information correctly or something, but the google documentation isn't very helpful. So I'm hoping someone can point out what I've missed?
Thanks!
Finally found an answer here that gave me exactly what I was looking for. Some simple example code that works! (why can't google do that?) It wasn't listed as the 'accepted' answer, it is the one below that but the accepted answer just tosses you toward a git that is ridiculously confusing for noobs.
Here is my edited my code above from above:
<head>
<script src='https://www.google.com/recaptcha/api.js?render=YOUR_KEY_HERE'></script>
</head>
<body>
<form name="contactform" action="send_form_email.php" method="post">
<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
<input type="hidden" name="action" value="validate_captcha">
<div class="input-group">
<span class="input-group-label">Name</span>
<input name="realname" class="input-group-field" type="text" value="Your Name Here" maxlength="50" onFocus="this.value=''">
</div>
<div class="input-group">
<span class="input-group-label">Email</span>
<input name="email" class="input-group-field" type="email" value="Your E-Mail Here" maxlength="50" onFocus="this.value=''">
</div>
<div class="input-group">
<span class="input-group-label">Message</span>
<textarea name="message" rows="10"></textarea>
</div>
<input type="Submit" class="button" value="SEND"><input type="Reset" class="button" value="RESET">
</form>
<script>
$(function(){ //wait for document ready
grecaptcha.ready(function() {
grecaptcha.execute('YOUR_KEY_HERE', {action: 'contactUs'}).then(function(token) {
// Verify the token on the server.
document.getElementById('g-recaptcha-response').value = token;
});
});
});
</script>
</body>
Then the revised PHP form called send_form_email.php that I'm using to take care of all the hard work:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Build POST request:
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = 'YOUR_SECRET_KEY';
$recaptcha_response = $_POST['g-recaptcha-response'];
// Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url.'?secret='.$recaptcha_secret.'&response='.$recaptcha_response);
$recaptcha = json_decode($recaptcha);
// Take action based on the score returned:
if ($recaptcha->score >= 0.5) {
// Basically if the score is equal to or better than the above, you have a good one and can send your email off and this is just where you would do that
}
} else {
// otherwise, let the spammer think that they got their message through
header('Location: success.htm');
exit();
}
}
?>
I've got it showing a 0.5 score for now, but you should of course check your admin on google and see what scores you are getting and adjust as needed.

Are there better solutions than redirect header location?

At the moment i'm preventing a resubmit with a redirect header location. But I imagine that the page loads slower because it's a waste of time to go to one place just to be redirected to another. It adds one extra step to the process.
What other options do I have with PHP?
Is there a way maybe to send form data to another file/page on submit without getting "redirected" to that page as well? And is it possible to do that without the need for redirect, because you where never sent there from the beginning. Just passing on the "form data" to the other page.
Open to other solutions as well, as long it's PHP.
Take care
Use include to include the PHP in your other page it will process the form without a redirect.
include 'YourFile.php';
here is a structural example of this.
<?php
include 'functions/db.php';// your db connection to process the form
$error['last'] = '';
$error['first'] = '';
$error['user'] = '';
if(isset($_POST['addUser'])){ // Check if form is submitted
$LastImp = $_POST['LastImp'];
$FirstImp = $_POST['FirstImp'];
$UserImp = $_POST['UserImp'];
if($LastImp == '' || $FirstImp == '' || $UserImp == ''){// Check if inputs are empty.
if($streetImp == ''){$error['street'] = 'Must enter a Street';}
if($LastImp == ''){$error['last'] = 'Must enter a Last Name';}
if($FirstImp == ''){$error['first'] = 'Must enter a First Name';}
if($UserImp == ''){$error['user'] = 'Must enter a Username';}
$error['alert'] = "All Fields are Required.";
include 'views/employee_front.php';
exit();
} else {
//Process the Form.
}}
include 'YourFile.php';// the php reads this first because all the other code is conditional upon submit.
This is YourFile Page
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<body>
<form method="post">
<div class="rowContainer">
<label class="User">Username</label>
<input class="Userimp" name="UserImp" type="text"></div>
<div class="error"><?php echo $error['user']; ?></div>
<div class="rowContainer">
<label class="First">First Name</label>
<input class="Firstimp" name="FirstImp" type="text"></div>
<div class="error"><?php echo $error['first']; ?></div>
<div class="rowContainer">
<label class="Last">Last Name</label>
<input class="Lastimp" name="LastImp" type="text"></div>
<div class="error"><?php echo $error['last']; ?></div>
<button class="addSubmitA" type="submit" name="addUser">Add User</button>
</form>
give the php file in action attribute of form tag <form method="POST" action="submit-data.php"> and in the submit-data.php,after successful data submission give header('Location:form.php') . It works fine for me without resubmission of data on browser reload. It is one way to prevent resubmission of data on page reload. Second way is use Ajax Jquery method to submit data.

google recaptcha response is null [PHP, localhost]

I need a little help for a problem with Google Recaptcha in a site I am developing in my pc (so localhost) before transferring to the open internet.
I signed up for Google Recaptcha and got a pair of keys. I created this form in a php page:
<div>
<form action="" method="POST" name="formEmail">
<section>
<ul class="formMail" id="ulMsg">
<li>
<label for="msg">Messagge</label>
</li><li>
<textarea class="datoForm autoExpand" name="msg" id="msg" placeholder="Type Msg" rows='3' data-min-rows='3'></textarea>
</li>
</ul>
</section>
<div class="formMail" id="captchaContainer">
<div class="g-recaptcha" data-sitekey="[Public_Key]"></div>
</div>
<br/><input type="button" value="Invia" onclick="formSubmit();">
</form>
</div>
Instead of a submit button I call a JS file to validate user input, if everything is fine I submit data to another php page which checks captcha too. Source of this php page is:
if(isset($_POST['g-recaptcha-response'])){$captcha=$_POST['g-recaptcha-response'];}
$secretKey = "[Private_Key]";
$ip = $_SERVER['REMOTE_ADDR'];
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$captcha."&remoteip=".$ip);
$responseKeys = json_decode($response,true);
Here is the problem: I don't get anything! I tried
var_dump($responseKeys);
but all I get is NULL. I do not get any other error, the captcha shows fine in the form and seems to work regularly. I am working in localhost, so my IP is 127.0.0.1, this should help but is useless. I do not have an "open" site to paste it and try, what am I doing wrong?
Just had the same problem. It was a <div> tag causing the problem.
My form was within a main <div> used to format the general layout of the form. The <form> tag doesn't HAVE to be within the main <div> I was using for the form layout. I moved the <form> tag just before my form layout <div> tag and it started working perfectly.
The same can happen with <table> tags. You need to start the <form> tag before any tables used for formatting the form.
So your problem is the <div> just before the <form>:
<div>
<form action="" method="POST" name="formEmail">
Just reverse the 2 tags and it will work fine:
<form action="" method="POST" name="formEmail">
<div>
According to the Google recaptcha documentation:
Method: POST
But you are sending a GET request on this line:
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$captcha."&remoteip=".$ip);
A solution has already been proposed here.
Inside HTML Tags :
<head>
<script src="https://www.google.com/recaptcha/api.js"></script>
</head>
<body>
<form action="" method="POST">
<div class="g-recaptcha" data-sitekey="PublicKey"></div>
<input type="submit" name="submit" value="Post comment">
</form>
</body>
Inside PHP Tags :
<?php
if(isset($_POST['submit'])) {
if( isset($_POST['g-recaptcha-response']) && !empty( $_POST['g-recaptcha-response'] ) ) {
$secret = 'PrivateKey';
$verifyResponse=file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
$responseData = json_decode($verifyResponse);
var_dump($responseData); //this line returns Null Value
if($responseData->success) {
// Logical Code
}
else {
echo 'Robot verification failed, please try again.';
}
}
}
?>

Php redirect on custom Post/get from webform

Hi all this is an easy question but right now i can't think about ..
I've a form where people can insert a personal code like "Abcdef301"
On submit i want to redirect them to url:
http://domain.tld/yoururls/Abcdef301
I've tried with some Post and Get (like the emails form but i've failed)
Any help?
<?php
if(isset($_POST['VAI'])) {
if(isset($_POST['text']) && $_POST['text'] != "") {
header("Location: http://domain.tld/yoururls/".$_POST['text']);
} else {
// handle error of no code in form field here if you want to
}
}
?>
<html>
<head>
<title>page title</title>
</head>
<div id="feedback-form">
<div class="success-block"></div>
<form action="" method="post">
<input name="text" placeholder="Inserire Codice Evento" required type="text">
<input type="submit" value="VAI" class="btn">
</form>
</div>
</html>
Should be what you're looking for.

PHP form not processing in process.php

I'm having difficulty figuring out why my PHP form is processing on process.php but not returning to the form page with the appropriate $messages. Am I missing a line of code? I wrote this all up myself and it's the first time.
Here is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Contact Form - jQuery</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<h3>Contact Us</h3>
<?php echo $contact_message; ?>
<form id="myForm" method="post" action="process.php">
<input name="name" type="text" value="<?php echo $_POST[name]; ?>" placeholder="Name" required/>
<br>
<input name="email" type="email" value="<?php echo $_POST[email]; ?>" placeholder="you#yourmail.com" required/>
<br>
<textarea name="message" class="message" placeholder="We can answer your questions." required>
<?php echo $_POST[message]; ?>
</textarea>
<br>
<button type="submit" name="submit" class="btn send">
<img src="img/send.png">
</button>
<br>
<?php echo $contact_success_message; ?>
</form>
<!--close contact form-->
</body>
</html>
And here is my process.php
<?php
//checks for valid email
function is_valid_email($email) {
$result = true;
$pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\#([a-z0-9])(([a-z0-9-])*([a-z0-9]))+(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i';
if(!preg_match($pattern, $email)) {
$result = false;
}
return $result;
}
//when send is pressed, validate fields
if(isset($_POST['submit'])) {
$valid = true;
$contact_message = '';
if ( $_POST['name'] == "" ) {
$contact_message .= "You forgot to tell us your name. ";
$valid = false;
}
if ( !is_valid_email($_POST['email']) ) {
$contact_message .= "A valid email is required, don't worry we don't share it with anyone. ";
$valid = false;
}
if ( $_POST['message'] == "" ) {
$contact_message .= "What did you want to ask us? ";
$valid = false;
}
//if everything checks out, send the message!
if ( $valid == true ) {
$safe_email = str_replace("\r\n","",$_POST[email]);
$mail = "From: $_POST[name]\n";
$mail .= "Email: $_POST[email]\n";
$mail .= "$_POST[message]\n";
mail('ME#MYEMAIL.COM','New Contact from RN+',$mail,"From: $safe_email\r\n");
$contact_success_message = 'Brilliant I say! We will be in contact with you shortly.';
//clear form when submission is successful
unset($_POST);
}
}
?>
I could have sworn that I've used this before but this time it's not returning to the contact page.
It looks like you meant to use the code like this:
form.php
<?php include 'process.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Contact Form - jQuery</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<h3>Contact Us</h3>
<?php echo $contact_message; ?>
<form id="myForm" method="post" action="process.php">
<input name="name" type="text" value="<?php echo $_POST[name]; ?>" placeholder="Name" required/><br>
<input name="email" type="email" value="<?php echo $_POST[email]; ?>" placeholder="you#yourmail.com" required/><br>
<textarea name="message" class="message" placeholder="We can answer your questions." required><?php echo $_POST[message]; ?></textarea><br>
<button type="submit" name="submit" class="btn send"><img src="img/se
__
formnd.png"></button><br>
<?php echo $contact_success_message; ?>
</form><!--close contact form-->
</body>
</html>
The form processor will set the appropriate variables you are outputting in your HTML code. Since process.php checks if the method is POST, you don't have to do that in the form page.
If you want process.php to redirect back to your form, you need to add a PHP header code like: header('Location: http://www.example.com/form.php');
If you want to carry through any data back to the original page, include it in the URL as a GET variable: header('Location: http://www.example.com/form.php?message='.$messagetext); You can then retrieve this on your form page through use of GET: echo $contact_success_message = $_GET['message'];
Do not forget to exit(); or die(); after your redirect!
If you don't have any reason for excluding a single PHP page, you could merge the two (form and process) into one php page.
<?php
//checks for valid email function
...
if(isset($_POST['submit'])) {
...
}
?>
...your HTML goes here...
This will display just the form if no data has been submitted, and if the form has been submitted will "reload" the page, perform the action, and display the appropriate message. Change the form action to action="" so the file will post to itself.
I would recommend using jQuery validation. It is easier and will help with any issues you might have in returning the message.
http://docs.jquery.com/Plugins/Validation
Something like this...
$("#myForm").validate({
rules: {
name: { required: true; }
},
messages: {
name: "You forgot to tell us your name.",
}
});
You can do this for email fields and for your whole form. You can find plenty of examples online.
Just include your other fields. If you do it this way the validation is client side and the form will process and then you forward to a thank you for contacting us page.

Categories