January 5, 2015 by Christoff Truter PHP Google API
I don't think I need to convince anyone of how annoying it can get to fill out a CAPTCHA - especially after your third attempt of trying to decipher some gibberish piece of text that you are seeing on the screen.
Unfortunately it is one of those necessary evils that developers can employ in an attempt to protect websites from bots.
Bots are however getting smarter all the time and even the most illegible CAPTCHA can now potentially be deciphered (perhaps we need to invert the mechanism now, if you can read this image, you are probably a bot?)
So its definitely a bit of an arms race going on..
While developing the latest version of this website, I initially opted for the honeypot approach e.g. add some field only a bot can see, but like the burglar bars on my windows it will only stop the casual criminal.
Enter Google's latest weapon, the no CAPTCHA reCAPTCHA.
I am not going to go into too much detail - I am sure if you watched the above video clip you will get the general idea.
If you didn't watch the clip, Google basically presents the user with a checkbox that they need to check in order to prove their humanity, while a threat detection engine running in the background attempts to verify that you are in fact human. If the engine feels there is sufficient reason to think you are a bot, it presents you with various CAPTCHA options that you can fill out. Read more about it here.
In this post I am going to implement this functionality using PHP, if anyone is unclear how to implement it in any other programming language, drop me a comment.
Firstly, you will need to register to get a site key and secret key to use on your website, that you can do over here.
<?php define('RECAPTCHA_SITEKEY', 'Sitekey as per google'); define('RECAPTCHA_SECRET', 'Secret as per google'); ?>
<html> <head> <script src='https://www.google.com/recaptcha/api.js'></script> </head> <body> <form method="POST"> <div class="g-recaptcha" data-sitekey="<?=RECAPTCHA_SITEKEY?>"></div> <button>Submit</button> </form> </body> </html>
<?php function IsVerified($responseKey = 'g-recaptcha-response') { if (!isset($_POST[$responseKey])) { return; } $jsonResult = GetJsonResult( 'https://www.google.com/recaptcha/api/siteverify', array( 'secret'=> RECAPTCHA_SECRET, 'response'=> $_POST[$responseKey], 'remoteip'=> GetRemoteIP() ) ); if (isset($jsonResult)) { return $jsonResult->success; } return false; } ?>
<?php function GetRemoteIP() { return $_SERVER['REMOTE_ADDR'] ?: $_SERVER['HTTP_X_FORWARDED_FOR'] ?: $_SERVER['HTTP_CLIENT_IP']; } function GetUrlResult($url, $args = NULL) { if (isset($args)) { $url.='?'.http_build_query($args); } $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $result = curl_exec($ch); curl_close ($ch); return $result; } function GetJsonResult($url, $args = NULL) { $jsonResult = GetUrlResult($url, $args); $json = json_decode($jsonResult); if (isset($json)) { return $json; } } ?>
The checkbox/site key response (see html tab), secret key and visitor's IP will need to be sent along with every request to Google's verification server, like seen in the verification snippet above. Google in turn responds with a JSON string, telling the PHP script if it was a successful request.
This is pretty much all there is to implementation.
The only complaints I've got so far, is that the CAPTCHA still seems to come up more often than not and that it isn't currently responsive - it is however small enough for most basic mobile screens.
But all of this will definitely greatly improve UX.
Honestly, I don't believe that you will ever find the silver bullet, even if we manage to perfect bot and spam detection, nothing will stop anyone to get a bunch of slaves to manually spam your site. Think of this as burglar bars though ;)
hi May 28, 2015 by redi
Great