Trouble with reCAPTCHA v3 verify score - php

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.

Related

missing-input-response | Invisible reCaptcha

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().

How to validate form using another php file?

I am new to web designing. Now, I have created a form, and if the user input doesn't meet the requirements I display error message, and if it does I do some mysql commands to enter the info to the database. Now one way to do this is to code the php file into the html and use this command,<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> like described [here][1]
But I don't want to put the script in the same file. How do I do that in another php file such that if user input is invalid, it will return to the homepage with the error message updated?
Here is my code
<!DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="register.css">
</head>
<h1>Register as A new user</h1>
<div id="signup">
<form id="registration_form" action="registration.php" method="post">
<p>
<label>Name</label>
<input type="text" name="name"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Email</label>
<input type="text" name="email"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Password</label>
<input type="password" name="passwd"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Repeat Password</label>
<input type="password" name="repasswd"/>
<span class="errorMessage"></span>
</p>
<input type="submit" class="button" value="sign up"/>
</form>
</div>
What should be in the registration.php? Like the link, I do everything, I set a flag to the error, Now if the flag is true I return the user to the homepage with the error messages, and if false, I show a message saying registration successful. How do I do the part,"return to homepage with the appended error message"?
All your validation and bulletproofing should be in the registration.php
stuff like this:
//both parameters are required, so make sure they were passed-in
if(!isset($_GET['name'])) {
die('Must pass \'name\');
//both parameters are required, so make sure they were passed-in
if(!isset($_GET['email'])) {
die('Must pass \'email\');
}
if(!isset($_GET['passwd'])) {
die('Must pass \'password\');
} else {
//do cool stuff here
}
Don't forget your JS validation as well for the front end. I really hope this helps and gives you a bit of direction.
put your validation codes in "validate.php" or any file name you like
then change the action to validate.php to
then in validate.php if validation matches the requirements.
header("Location: registration.php");
if not match
header("Location: back to the httml with form.php");
You can learn form validation here : http://allitstuff.com/registration-form-in-php-with-validation/

How to do a ajax request for login

I have this in my PHP code, and it currently does the login request in the same login.php page but now i want to do it with Ajax. Basically I have this in the login.php
echo '<form method="post" ><div id="login" class="login">
<label for="login">User Name</label>
<input type="text" name="logInUsername" />
<label for="Password">Password</label>
<input type="password" name="logInPassword" />
<input type="submit" value="Submit" name="submitlogin" class="button" />
</div>';
I would like to still use this but have a login_request.php or something where i can send the username and password validated and then change the <div id=login> to say you are logged in!</div> I can do it the conventional way, with the form post .. but now I would like to try it with Ajax.
Any help will be much appreciated.
Regards
What have you tried so far? This is how I would start:
This should get you started:
HTML:
<form id="loginForm">
<div id="login" class="login">
<label for="login">User Name</label>
<input type="text" name="logInUsername" />
<label for="Password">Password</label>
<input type="password" name="logInPassword" />
<input type="button" value="Submit" id="submitlogin" class="button" />
</div>
</form>
jQuery:
$("#submitlogin").click(function() {
inputs = //grab then inputs of your form #loginform
$.ajax ({
url: "urltoyourloginphp.php",
data: inputs,
success: function() {
$("#login").html("You are now logged in!");
}
});
})
I wrote this a while ago, it's not quite a full ajax login (i.e. at the end it does still redirect you), but it may serve as a basis for a full ajax login. As a plus you actually don't need https (that was the whole point of this little project).
https://github.com/eberle1080/secure_http_login/blob/master/login.php
The high level steps go something like this:
Ask the server for a seed value (a salt) using an ajax request
Hash the password + seed using a sha1 sum
Ask the server to verify the username and salted + hashed password
If it's valid, the server sets a session cookie indicating that the user is logged in
The server responds to the ajax request with a success / fail message
jQuery has built in .post() and .serialize() methods for wrapping up a form.
$.post("login.php", $("#loginForm").serialize(), function(data) {
//pass information back in with data. if it's JSON, use $.parseJSON() to parse it.
alert('either logged in or errored');
);
You will also need to edit your form so it has an id, like: <form id="loginForm">...
I don't know PHP but will give you an example of how I would have done it with vbscript (classic asp) so you may try to adapt it to PHP as needed.
I, in my applications, don't use the form tag since I first used ajax. So, here we go:
login html page:
include jquery
<script type='text/javascript' src='your-jquery-url'></script>
<script type='text/javascript'>
function tryLogin() {
var inputs='userName='+$('logInUsername').val()+
'&userPassw='+$('logInPassword').val();
//notice that I changed your name= to id= in the form
//notice the '&' in the '&userPassw=
$.post('your-login-validation-page',inputs,function(data) {
eval('var json='+data);
if (json['success'] == 'true') {
$('#loginForm').html('<p>Congratulations! You\'ve been logged in successfully</p>')
} else {
alert(json['errorMessage']);
$('#logInUsername').focus();
}
});
}
</script>
<div id='loginForm' >
<label for="login">User Name</label>
<input type="text" id="logInUsername" />
<label for="Password">Password</label>
<input type="password" id="logInPassword" />
<button onClick='tryLogin(); ' >LOGIN</button>
</div>
login-validation-page
[in vbscript]
user = request.Form("userName")
passw = request.Form("userPassw")
"if is there this user" (coded as if there was a database look up...)
"if the password = passw" (coded as comparing the values)
response.write "{'sucess':'true'}"
else
response.write "{'success':'false','errorMessage':'wrong password'}"
end if
else
response.write "{'success':'false','errorMessage':'user not found'}"
end if
---> end of login-validation-page

POST without redirect with PHP

I have a simple form for a mailing list that I found at http://www.notonebit.com/projects/mailing-list/
The problem is when I click submit all I want it to do is display a message under the current form saying "Thanks for subscribing" without any redirect. Instead, it directs me to a completely new page.
<form method="POST" action="mlml/process.php">
<input type="text" name="address" id="email" maxlength="30" size="23">
<input type="submit" value="" id="submit"name="submit" >
</form>
You will need AJAX to post the data to your server. The best solution is to implement the regular posting, so that will at least work. Then, you can hook into that using Javascript. That way, posting will work (with a refresh) when someone doesn't have Javascript.
If found a good article on posting forms with AJAX using JQuery .
In addition, you can choose to post the data to the same url. The JQuery library will add the HTTP_X_REQUESTED_WITH header, of which you can check the value in your server side script. That will allow you to post to the same url but return a different value (entire page, or just a specific response, depending on being an AJAX request or not).
So you can actually get the url from your form and won't need to code it in your Javascript too. That allows you to write a more maintanable script, and may even lead to a generic form handling method that you can reuse for all forms you want to post using Ajax.
Quite simple with jQuery:
<form id="mail_subscribe">
<input type="text" name="address" id="email" maxlength="30" size="23">
<input type="hidden" name="action" value="subscribe" />
<input type="submit" value="" id="submit"name="submit" >
</form>
<p style="display: none;" id="notification">Thank You!</p>
<script>
$('#mail_subscribe').submit(function() {
var post_data = $('#mail_subscribe').serialize();
$.post('mlml/process.php', post_data, function(data) {
$('#notification').show();
});
});
</script>
and in your process.php:
<?php
if(isset($_POST['action'])) {
switch($_POST['action']) {
case 'subscribe' :
$email_address = $_POST['address'];
//do some db stuff...
//if you echo out something, it will be available in the data-argument of the
//ajax-post-callback-function and can be displayed on the html-site
break;
}
}
?>
It redirects to a different page because of your action attribute.
Try:
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="text" name="address" id="email" maxlength="30" size="23" />
<input type="submit" value="" id="submit" name="submit" />
</form>
<?php if (isset($_POST['submit'])) : ?>
<p>Thank you for subscribing!</p>
<?php endif; ?>
The page will show your "Thank You" message after the user clicks your submit button.
Also, since I don't know the name of the page your code is on, I inserted a superglobal variable that will insert the the filename of the currently executing script, relative to the document root. So, this page will submit to itself.
You have to use AJAX. But that requires JavaScript to be active at the users Brwoser.
In my opinion it's the only way to do without redirect.
to send a form request without redirecting is impossible in php but there is a way you can work around it.
<form method="post" action="http://yoururl.com/recv.php" target="_self">
<input type="text" name="somedata" id="somedata" />
<input type="submit" name="submit" value="Submit!" />
</form>
then for the php page its sending to have it do something but DO NOT echo back a result, instead simply redirect using
header( 'Location: http://yourotherurl.com/formpage' );
if you want it to send back a success message simply do
$success = "true";
header( 'Location: http://yourotherurl.com/formpage?success='.$success);
and on the formpage add
$success = $_GET['success'];
if($success == "true"){ echo 'Your success message'; } else { echo
'Your failure message';
Return and print the contents of another page on the current page.
index.php
<html>
<body>
<p>index.php</p>
<form name="form1" method="post" action="">
Name: <input type="text" name="search">
<input type="submit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$_POST['search'];
include 'test.php';
}
?>
</body>
</html>
test.php
<?php
echo 'test.php <br/>';
echo 'data posted is: ' . $_POST['search'];
?>
Result:
Just an idea that might work for you assuming you have no control over the page you are posting to:
Create your own "proxy php target" for action and then reply with the message you want. The data that was posted to your php file can then be forwarded with http_post_data (Perform POST request with pre-encoded data). You might need to parse it a bit.
ENGLISH Version
It seems that no one has solved this problem without javascript or ajax
You can also do the following.
Save a php file with the functions and then send them to the index of your page
Example
INDEX.PHP
<div>
<?php include 'tools/edit.php';?>
<form method="post">
<input type="submit" name="disable" value="Disable" />
<input type="submit" name="enable" value="Enable" />
</form>
</div>
Tools.php (It can be any name, note that it is kept in a folder lame tools)
<?php
if(isset($_POST['enable'])) {
echo "Enable";
} else {
}
if(isset($_POST['disable'])) {
echo "Disable";
} else {
}
?>
Use
form onsubmit="takeActions();return false;"
function takeAction(){
var value1 = document.getElementById('name').innerHTML;
// make an AJAX call and send all the values to it
// Once , you are done with AJAX, time to say Thanks :)
document.getElementById('reqDiv').innerHTML = "Thank You for subscribing";
}

Contact form using PHP and jQuery form plugin

I'm using the jQuery Form plugin to submit AJAX requests. It's a simple contact from using this PHP script: http://pastie.org/725652 - the only validation happens inside the PHP.
Here's my Javascript code to trigger the whole thing:
$('#contactform').ajaxForm({
target: '#error',
beforeSubmit: function() {
$('#error').append('<p class="loading">Sending your message...</p>');
},
success: function() {
$('#error p.loading').fadeOut();
$('#error').fadeIn('slow');
}
});
Unfortunately, it doesn't seem to work. The PHP works perfectly, sends the email and returns the success message, but the AJAX magic isn't working for some reason. Obviously what I want to achieve, is to display the message returned by the PHP script via AJAX in the <div id="error />
I used the same script many times and never had any problems with it, now I can't figure out why it doesn't work. Here's the markup for the contact form.
<form id="contactform" class="group" method="post" action="submitemail.php">
<fieldset>
<div><label for="first-name">First Name</label>
<input type="text" name="first-name" value="Jeremy" /></div>
<div class="alt"><label for="last-name">Last Name</label>
<input type="text" name="last-name" value="Anderson" /></div>
<div><label for="email">E-mail <span>(never published)</span></label>
<input type="text" name="email" value="jeremyanderson#mywebsite.com" /></div>
<div class="alt"><label for="url">Website</label>
<input type="text" name="url" value="http://www.mywebsite.com" /></div>
<label for="question">Message</label>
<textarea name="question" id="" cols="30" rows="10">Thinking of something to say...</textarea>
<input type="submit" name="submit" id="submit" value="Send E-mail" />
<div id="error"></div>
</fieldset>
</form>
Here's the code of the jQuery plugin if it can be any help. http://pastie.org/726175
If anyone could look at the whole thing and provide some tips why would it not work, I would be very grateful, thanks in advance!
you must include the parameters in which are the response from PHP:
EDIT:
try with these changes, in this example I'm separating the message "loading" with the response message.
HTML:
<form id="contactform" class="group" method="post" action="submitemail.php">
<fieldset>
<!-- fields -->
<input type="submit" name="submit" id="submit" value="Send E-mail" />
<div id="error"><span id="eloading"></span><span id="eresponse"></span></div>
</fieldset>
</form>
Javascript:
$('#contactform').ajaxForm({
target: '#eresponse',
beforeSubmit: function() {
$('#eresponse').hide('slow');
$("#eloading").append("<p class=\"loading\">Sending your message...</p>");
},
success: function(responseText, statusText) {
alert("test status: " + statusText + "\n\nresponseText: \n" + responseText);
$("#eloading").empty();
$('#eresponse').show('slow');
}
});
It didn't do the trick :( It still
goes to the submitemail.php file with
the success message instead of showing
the message in #error. – Justine 39
mins ago
If this happens that means the function attached to the submit event didnt end with
return false;
i beleive with ajaxForm this is done automagically so that means there is an error in your code somewhere. If you dont have firebug installed, install it and keep an eye on the console make sure:
jquery is loading ok
there are no
errrors setting up the ajax
interaction or in any other js on
the page that may stop it

Categories