Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reCaptcha file_get_contents(): SSL operation failed

I'm using Google reCaptcha for my webpage.

In testing mode everything works fine. No SSL.

When I test my webpage in production environment the following errors occures:

Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php on line 68

Warning: file_get_contents(): Failed to enable crypto in /vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php on line 68

Warning: file_get_contents(https://www.google.com/recaptcha/api/siteverify): failed to open stream: operation failed in /vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php on line 68
["invalid-json"]

I'm calling the reCaptcha API like this:

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
                async defer></script>

as described on the developer page from google.

I'm hosting my webpage at hoststar.ch. There is TSL 1.2 running.

I hope somebody could help me.

like image 484
Ilario Engler Avatar asked Nov 21 '15 23:11

Ilario Engler


2 Answers

In response to your last comment I realise you cannot change Google's reCaptcha api - what I meant was simply to do a file_get_contents actually on example.com ( it does exist ) as a test to see if you can retrieve any content using that method as some webhosts disable the associated functionality.

However, with respect to the Google reCatcha API you might need to specify additional parameters to the file_get_contents function call, notably setting the context options specifically for SSL.

$secret = 'Your google secret';
$captcha = trim( $_POST['g-recaptcha-response'] );
$ip = $_SERVER['REMOTE_ADDR'];
$url = "https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$captcha}&remoteip={$ip}";

$options=array(
    'ssl'=>array(
        'cafile'            => '/path/to/cacert.pem',
        'verify_peer'       => true,
        'verify_peer_name'  => true,
    ),
);
$context = stream_context_create( $options );
$res=json_decode( file_get_contents( $url, FILE_TEXT, $context ) );
if( $res->success ){/* all good */}
else{ /* captcha failed */ }

If you don't already have a copy of cacert.pem or ca-bundle.crt you can download them from their respective links. The path to the cafile can use either - save a copy to your host and correct the path to suit your environment.

like image 53
Professor Abronsius Avatar answered Sep 28 '22 07:09

Professor Abronsius


Change file_get_contents to curl. Here is the code,

Change-

$verify=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$response}");
 $captcha_success=json_decode($verify);  /*store json response*/

To this code :

$ch = curl_init("https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$response}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$verify = curl_exec($ch);

$captcha_success=json_decode($verify);  /*store json response*/

Please note $secret is the secret key stored on server side and $response is the recaptcha response send through post from front end.

like image 25
Nabil Mohammed Nalakath Avatar answered Sep 28 '22 07:09

Nabil Mohammed Nalakath