-
-
Save jonathanstark/dfb30bdfb522318fc819 to your computer and use it in GitHub Desktop.
# | |
# Verify captcha | |
$post_data = http_build_query( | |
array( | |
'secret' => CAPTCHA_SECRET, | |
'response' => $_POST['g-recaptcha-response'], | |
'remoteip' => $_SERVER['REMOTE_ADDR'] | |
) | |
); | |
$opts = array('http' => | |
array( | |
'method' => 'POST', | |
'header' => 'Content-type: application/x-www-form-urlencoded', | |
'content' => $post_data | |
) | |
); | |
$context = stream_context_create($opts); | |
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context); | |
$result = json_decode($response); | |
if (!$result->success) { | |
throw new Exception('Gah! CAPTCHA verification failed. Please email me directly at: jstark at jonathanstark dot com', 1); | |
} |
This has a serious problem:
if (!$result->success) {
does not suffices, as success may be returned but as false.
if (!$result->success || $result !== true)
is a fix.
Steps to reproduce:
Replay request containing the captcha -> it will yield success = false & error code.
Useful in some situations, thank you!
@ozzi- reCAPTCHA response always has success
property, and it is true
when user succeeded and false
if doesn't.
So !$result->success
means "'success' property of '$result' not equals true", which is sufficent to know if user failed to pass test.
However, you might want to replace that with empty($result->success)
so it won't throw you E_NOTICE when request failed and json_decode
returned false
.
Thanks!
Thanks a lot!!
Thanks!
Nice one!
This one will work if 'allow_url_fopen' is disabled on your server:
https://gist.github.com/diversen/8184ecfe8b796dc809c3cb2c514003a0
Thanks
The correct method of checking result should be:
if (!$result->success || empty($result->success)) {
}
Thank you, actually, empty
check should be enough:
if (empty($result->success)) {
}
This is great solution, thanks for this. I made an more spicy solution:
function validate_rechapcha($response){
// Verifying the user's response (https://developers.google.com/recaptcha/docs/verify)
$verifyURL = 'https://www.google.com/recaptcha/api/siteverify';
// Collect and build POST data
$post_data = http_build_query(
array(
'secret' => 'YOUR_SECRET_KEY',
'response' => $response,
'remoteip' => (isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER['REMOTE_ADDR'])
)
);
// Send data on the best possible way
if(function_exists('curl_init') && function_exists('curl_setopt') && function_exists('curl_exec')) {
// Use cURL to get data 10x faster than using file_get_contents or other methods
$ch = curl_init($verifyURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-type: application/x-www-form-urlencoded'));
$response = curl_exec($ch);
curl_close($ch);
} else {
// If server not have active cURL module, use file_get_contents
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create($opts);
$response = file_get_contents($verifyURL, false, $context);
}
// Verify all reponses and avoid PHP errors
if($response) {
$result = json_decode($response);
if ($result->success===true) {
return true;
} else {
return $result;
}
}
// Dead end
return false;
}
This is a much faster, universal and more flexible solution.
This is great solution, thanks for this. I made an more spicy solution:
function validate_rechapcha($response){ // Verifying the user's response (https://developers.google.com/recaptcha/docs/verify) $verifyURL = 'https://www.google.com/recaptcha/api/siteverify'; // Collect and build POST data $post_data = http_build_query( array( 'secret' => 'YOUR_SECRET_KEY', 'response' => $response, 'remoteip' => (isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER['REMOTE_ADDR']) ) ); // Send data on the best possible way if(function_exists('curl_init') && function_exists('curl_setopt') && function_exists('curl_exec')) { // Use cURL to get data 10x faster than using file_get_contents or other methods $ch = curl_init($verifyURL); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-type: application/x-www-form-urlencoded')); $response = curl_exec($ch); curl_close($ch); } else { // If server not have active cURL module, use file_get_contents $opts = array('http' => array( 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $post_data ) ); $context = stream_context_create($opts); $response = file_get_contents($verifyURL, false, $context); } // Verify all reponses and avoid PHP errors if($response) { $result = json_decode($response); if ($result->success===true) { return true; } else { return $result; } } // Dead end return false; }
This is a much faster, universal and more flexible solution.
This worked well for me. I had issues with using file_get_contents on a certain server, possibly due to permissions and access, so good ol' curl did the trick.
This is great solution, thanks for this. I made an more spicy solution:
function validate_rechapcha($response)
{
// Verifying the user's response (https://developers.google.com/recaptcha/docs/verify)
$verifyURL = 'https://www.google.com/recaptcha/api/siteverify';
$query_data = [
'secret' => 'Key',
'response' => $response,
'remoteip' => (isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER['REMOTE_ADDR'])
];
// Collect and build POST data
$post_data = http_build_query($query_data, '', '&');
// Send data on the best possible way
if (function_exists('curl_init') && function_exists('curl_setopt') && function_exists('curl_exec'))
{
// Use cURL to get data 10x faster than using file_get_contents or other methods
$ch = curl_init($verifyURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-type: application/x-www-form-urlencoded'));
$response = curl_exec($ch);
curl_close($ch);
}
else
{
// If server not have active cURL module, use file_get_contents
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create($opts);
$response = file_get_contents($verifyURL, false, $context);
}
// Verify all reponses and avoid PHP errors
if ($response)
{
$result = json_decode($response);
if ($result->success === true)
{
return true;
}
else
{
return $result;
}
}
// Dead end
return false;
}
Change http_build_query($query_data, '', '&');
Error Code 0xc000001
How do i render the captcha after clicking the button but before the ajax response is shown?
Works like a charm! Thank you very much!