Skip to content

Instantly share code, notes, and snippets.

@martinburger
Last active May 22, 2017 14:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinburger/f9f37770c655c25d5f7b179278815084 to your computer and use it in GitHub Desktop.
Save martinburger/f9f37770c655c25d5f7b179278815084 to your computer and use it in GitHub Desktop.
reCAPTCHA without <form> / AJAX only (http://stackoverflow.com/a/36674977/66981)
<h2>reCAPTCHA without form / AJAX only</h2>
<div class="panel panel-warning" id="panel-recaptcha">
<div class="panel-heading">
<h3 class="panel-title">Captcha</h3>
</div>
<div class="panel-body">
<div id="recaptcha-service" class="g-recaptcha"
data-callback="recaptchaCallback"
data-sitekey=""></div>
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=en"></script>
</div>
</div>
<div id="result"></div>
<script id="tmpl-alert" type="text/x-jsrender">
<div class="alert alert-warning alert-dismissible fade in" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<strong>Oh snap! You got an error...</strong> Please try again.
</div>
</script>
<script id="tmpl-service" type="text/x-jsrender">
{{for data}}
{{:}}<br>
{{/for}}
</script>
<?php
header('Content-Type: application/json');
$data_payload = array(/* Add static payload here. If not static, you might want to add it conditionally. */);
// see https://www.google.com/recaptcha/admin for details
$siteKey = '';
$secret = '';
// see https://developers.google.com/recaptcha/docs/language for details
$lang = 'en';
// the following origins are allowed to use this service
// (we accept requests only if the Origin header contains only those white-listed origins)
$allowed_http_origins = array(
"http://example.com",
"http://example.net",
// running Hugo server locally
"http://localhost:1313",
);
$http_origin = $_SERVER['HTTP_ORIGIN'];
if (in_array($http_origin, $allowed_http_origins)){
header("Access-Control-Allow-Origin: " . $http_origin);
}
// autoloader for ReCaptcha\Foo classes
require_once __DIR__ . '/vendor/autoload.php';
if (isset($_POST['g-recaptcha-response'])) {
// user's response has been POSTed via g-recaptcha-response
// $recaptcha = new \ReCaptcha\ReCaptcha($secret);
// file_get_contents() with URLs is disabled on our PHP installation
// (allow_url_fopen is set to false for security reasons)
// thus, we use implementation that makes use of fsockopen() instead
$recaptcha = new \ReCaptcha\ReCaptcha($secret, new \ReCaptcha\RequestMethod\SocketPost());
$resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
if ($resp->isSuccess()) {
// user has succeeded
echo json_encode(
array(
'success' => true,
'data' => $data_payload,
)
);
} else {
// user has failed or something went wrong
echo json_encode(
array(
'success' => false,
// just forward reCAPTCHA's error codes
// see https://developers.google.com/recaptcha/docs/verify#error-code-reference for details
// for instance, 'missing-input-response' means that the submitted response was empty
'error-codes' => $resp->getErrorCodes(),
)
);
}
} else {
// user's response has *not* been POSTed via g-recaptcha-response
echo json_encode(
array(
'success' => false,
// use own error code
'error-codes' => array('g-recaptcha-response-not-posted'),
)
);
}
?>
// callback function has to be in global namespace
// see https://github.com/google/recaptcha/issues/74#issuecomment-148071465 for details
window.recaptchaCallback = undefined;
jQuery(document).ready(function($) {
window.recaptchaCallback = function recaptchaCallback(response) {
// console.log('CALLBACK - captcha response: ' + response);
$.ajax({
method: "POST",
url: "http://example.com/service.ajax.php",
data: { 'g-recaptcha-response': response },
})
.done(function(msg) {
// console.log(msg);
if (msg.success === true) {
// hide panel that contains recaptcha challenge...
$("#panel-recaptcha").hide();
// ... and show service result instead
var tmpl = $.templates("#tmpl-service");
$("#result").html(tmpl.render({data: msg.data}));
} else {
// show alert message
var tmpl = $.templates("#tmpl-alert");
$("#result").html(tmpl.render());
}
})
.fail(function(jqXHR, textStatus) {
// show alert message
var tmpl = $.templates("#tmpl-alert");
$("#result").html(tmpl.render());
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment