reCaptcha file_get_contents(): SSL operati

2019-05-08 18:37发布

问题:

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.

回答1:

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.



回答2:

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.