23

I integrated Googles funky ReCaptcha NoCaptcha into a simple html5 form. On localhost it is working, but testing online it always returns the error 'invalid-json'. Here is part of my code:

$secret = 'TEHSEHCRET';
$recaptcha = new \ReCaptcha\ReCaptcha($secret);
$resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
if ($resp->isSuccess()) {
// do some
}
else {
print_r($errors = $resp->getErrorCodes());
}

Returns Array ( [0] => invalid-json )

I googled for some help but found nothing really helpful.

Since the code on- and offline is the same I am really clueless where the problem is coming from. https://developers.google.com/recaptcha/docs/verify says nothing about the error code. Guess the solution is too simple.

SeinopSys
  • 8,787
  • 10
  • 62
  • 110
Tommy
  • 851
  • 9
  • 24

8 Answers8

56

I had the same issue and fixed it by using cURL as request method instead POST.

$recaptcha = new \ReCaptcha\ReCaptcha($secret, new \ReCaptcha\RequestMethod\CurlPost());
xkeshav
  • 53,360
  • 44
  • 177
  • 245
CalleKhan
  • 1,608
  • 1
  • 14
  • 16
12

The key to the solution was to simply turn on the php errors (I know, it's embarrassing). This delivered the error that kept me struggling and also delivered the solution at the same time:

PHP had problems connecting to the https verifying page of google. That was just because of a single option in the php.ini: allow_url_fopen

php.net description:

allow_url_fopen boolean

This option enables the URL-aware fopen wrappers that enable accessing URL object like files. Default wrappers are provided for the access of remote files using the ftp or http protocol, some extensions like zlib may register additional wrappers.

Changing its value from 0 to 1 solved my problem. Shows even more how important it is to turn on php errors when developing (I am a super noob to php programming)

Hope this helps somebody some time!

Community
  • 1
  • 1
Tommy
  • 851
  • 9
  • 24
  • 2
    Thank you man. It helped me to realize what is actually wrong. I used https://github.com/google/recaptcha with sockets method. Thanks again – tomexx Jun 03 '15 at 11:11
  • 2
    You are absolutely correct. `allow_url_fopen` needs to be true. Or you can use `$recaptcha = new \ReCaptcha\ReCaptcha($secret, new \ReCaptcha\RequestMethod\CurlPost());` --> That always works. – desloovere_j May 04 '18 at 14:37
3

This solved it for me:

//$recaptcha = new \ReCaptcha\ReCaptcha($secret);

// If file_get_contents() is locked down on your PHP installation to disallow
// its use with URLs, then you can use the alternative request method instead.
// This makes use of fsockopen() instead.
$recaptcha = new \ReCaptcha\ReCaptcha($secret, new \ReCaptcha\RequestMethod\SocketPost());
Jahid
  • 21,542
  • 10
  • 90
  • 108
2

If you are using reCAPTCHA PHP client library < 1.2.4 with SocketPost request method then you need to update to ≥ 1.2.4 or you should switch to CurlPost because the Google server response has changed: https://github.com/google/recaptcha/issues/359

yenshirak
  • 3,021
  • 2
  • 21
  • 27
2

I was getting same issue. I was fixed this issue by replacing 'SocketPost' with 'CurlPost'.

Replaced

$recaptcha = new \ReCaptcha\ReCaptcha(SECRET_KEY, new \ReCaptcha\RequestMethod\SocketPost());

With

$recaptcha = new \ReCaptcha\ReCaptcha(SECRET_KEY, new \ReCaptcha\RequestMethod\CurlPost());
Shabnam Khan
  • 67
  • 2
  • 10
1

// Make the call to verify the response and also pass the user's IP address

  $resp = $recaptcha->verify($recaptcha_response, $this->CI->input->ip_address());
Prafulla Kumar Sahu
  • 9,321
  • 11
  • 68
  • 105
Umar Adil
  • 5,128
  • 6
  • 29
  • 47
1

use ReCaptcha\ReCaptcha;
use ReCaptcha\RequestMethod;
use ReCaptcha\RequestParameters;
use ReCaptcha\RequestMethod\CurlPost;

class NotSSLCurl extends CurlPost implements RequestMethod
{
    public function __construct()
    {
        $this->curl = curl_init(self::SITE_VERIFY_URL);
        curl_setopt($this->curl, CURLINFO_HEADER_OUT, 0);
        curl_setopt($this->curl, CURLOPT_HEADER, 0);
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl, CURLOPT_BINARYTRANSFER,1);
        curl_setopt($this->curl, CURLOPT_TIMEOUT, 9999);
        curl_setopt($this->curl, CURLOPT_USERAGENT, 'Mozilla/5.0');
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($this->curl, CURLOPT_POST , 1);
        curl_setopt($this->curl, CURLOPT_HTTPHEADER , array('Content-Type: application/x-www-form-urlencoded'));
    }

    public function submit(RequestParameters $params)
    {
        curl_setopt($this->curl, CURLOPT_POSTFIELDS , $params->toQueryString());
        return curl_exec($this->curl);
    }

    public function __destruct()
    {
        curl_close($this->curl);
    }
}

// example validation:
$recaptcha = new ReCaptcha('CLIENT_SECRECT', new NotSSLCurl());
$resp      = $recaptcha->verify(@$_POST['g-recaptcha-response'],$_SERVER['REMOTE_ADDR']);
var_dump($resp->isSuccess());
Flavio Salas
  • 320
  • 2
  • 5
-1

the response is a json object. it should be decoded first. i am pretty new to web programming/development, but i successfully integrated google recaptcha on an asp.net test site which does nothing for now, but i'm sure it handles the json response just the way i want it to..

found another, could this help.

panda.o24
  • 1,888
  • 1
  • 13
  • 14
  • So I finally tried it last night. Starting with the fact, the this tut is using a slightly older version of ReCaptcha I thought I might give it a chance anyways. It still did not work; I didn't even got any errors. phew – Tommy May 11 '15 at 04:24
  • sorry, the codes i used for my test were in asp.net and c# on back end, i dont know how on ajax.. but, i think you have to deserialize the json object.. and then parse the resulting string response.. – panda.o24 May 11 '15 at 05:54