Skip to content

Instantly share code, notes, and snippets.

@mikelfo
Last active July 17, 2018 13:17
Show Gist options
  • Save mikelfo/4303a65ec303ffd30a73cb0c478cb360 to your computer and use it in GitHub Desktop.
Save mikelfo/4303a65ec303ffd30a73cb0c478cb360 to your computer and use it in GitHub Desktop.
a simple service to use Google reCaptcha on Symfony 2.8
<?php
/**
* Description of recaptcha service which uses the ReCaptcha API by Google
* @see https://www.google.com/recaptcha
* @important Requires a Google account @see https://www.google.com/recaptcha/admin - property "Your property"
*
* @version 1.0.3
*
* @requires Buzz HTTP library. https://github.com/sensiolabs/SensioBuzzBundle
* and cUrl (php5-curl), etc.
*
* @author Mikel Fernández <mikel.fernandez (at) owasys.com>
* @copy (C) 2015 Owasys (https://www.owasys.com)
* @license MIT
*/
namespace MyApp\MyBundleBundle\Services;
use Symfony\Component\HttpFoundation\Request as Request;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
/**
* ReCaptcha class
*/
class ReCaptcha {
const API_URL = "https://www.google.com/recaptcha/api/siteverify";
/**
* site identifier to use the google recaptcha service
* this goes into the HTML form like this <div class="g-recaptcha form-control" data-sitekey="{{ google_recaptcha_sitekey }}"></div>
* @important added to app parameters (to be passed to twig) but not needed for this service
*/
//private $siteKey;
/**
* account identifier (APIKey) for recaptcha API requests
*/
private $siteSecret;
private $captchaDisabled;
private $logger;
private $container;
public function __construct($logger, Container $container, $siteSecret, $useCaptcha = TRUE) {
$this->logger = $logger;
$this->container = $container;
$this->siteSecret = $siteSecret; // inject config parameter to this service %site_secret%
$this->captchaDisabled = !$useCaptcha;
}
/**
* Checks the captcha string against the ReCaptcha service by Google
* @see https://developers.google.com/recaptcha/docs/verify
* @param string $captcha
* @param string $ip
* @return boolean
*/
private function check($captcha = '', $ip = NULL) {
$buzz = $this->container->get('buzz');
$headers = ['Content-Type', 'application/x-www-form-urlencoded'];
$toBeSent = array(
'secret' => $this->siteSecret,
'response' => $captcha,
);
if ($ip) {
$toBeSent['remoteip'] = $ip;
}
$response = $buzz->post(ReCaptcha::API_URL, $headers, json_encode($toBeSent));
$resp = json_decode($response->getContent());
return $resp->success;
}
/**
* Check the Google Recaptcha services before processing a public form
* Log the failed attempts in standard Symfony log
* @param Request $request
* @return boolean
*/
public function captchaIsValid(Request $request) {
$clientIp = $request->getClientIp();
//$this->logger->info('before check: '.$request->request->get('g-recaptcha-response'));
$country = $this->container->get('owasys_web.ip_info_db')->getCityFromIP($clientIp);
if ($this->check($request->request->get('g-recaptcha-response'), $clientIp) || $this->captchaDisabled) {
$this->logger->info('Google ReCaptcha ' . ($this->captchaDisabled ? "DISABLED" : "OK") . ' :: client IP ' . $request->getClientIp() . ' (' . $country['name'] . ', ' . $country['region'] . ', ' . $country['city'] . ') :: host ' . $request->server->get('HTTP_HOST') . ' :: UA ' . $request->server->get('HTTP_USER_AGENT') . ' :: lang: ' . $request->server->get('HTTP_ACCEPT_LANGUAGE'));
//all went well, this client is not a robot or captcha is disabled
return true;
} else {
$this->logger->warn('Google ReCaptcha failed :: client IP ' . $clientIp . ' (' . $country['name'] . ', ' . $country['region'] . ', ' . $country['city'] . ') :: host ' . $request->server->get('HTTP_HOST') . ' :: UA ' . $request->server->get('HTTP_USER_AGENT') . ' :: lang: ' . $request->server->get('HTTP_ACCEPT_LANGUAGE'));
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment