reCaptcha file_get_contents(): SSL操作失败

6

我在网页中使用 Google reCaptcha。

在测试模式下一切正常,没有 SSL。

当我在生产环境下测试我的网页时,出现以下错误:

警告:file_get_contents():SSL 操作失败,错误代码为 1。OpenSSL 错误消息:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php 的第 68 行

警告:file_get_contents():无法启用加密,在 /vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php 的第 68 行

警告:file_get_contents(https://www.google.com/recaptcha/api/siteverify):操作失败,无法打开流,在 /vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php 的第 68 行
["invalid-json"]

我是这样调用 reCaptcha API 的:

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

如Google开发者页面所述。

我将我的网页托管在hoststar.ch上。 运行TSL 1.2。

我希望有人能帮助我。


你是否通过https调用了Google的JavaScript文件?直播主机是否允许使用file_get_contents获取URL? - Professor Abronsius
@RamRaider 第二个问题我不知道,得问hoststar。 - Ilario Engler
尝试在测试页面和生产网站上使用file_get_contents('http://example.com/'),看看会发生什么。如果你得到了响应,那么主机允许fopen封套,否则你可能需要重新考虑... - Professor Abronsius
@RamRaider 如果我执行 HTTP 请求,它可以工作,但是如果我执行 HTTPS 请求就不能工作… 我无法更改 reCaptcha API。 - Ilario Engler
2个回答

4
作为回应你的最后一条评论,我意识到你无法更改谷歌的reCaptcha api - 我的意思只是简单地在example.com上进行一个file_get_contents测试(它确实存在),以查看是否可以使用该方法检索任何内容,因为某些web主机会禁用相关功能。
然而,关于Google reCatcha API,你可能需要指定额外的参数来调用file_get_contents函数,特别是为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 */ }

如果你还没有 cacert.pem 或者 ca-bundle.crt 的副本,你可以从它们各自的链接下载。对于 cafile 的路径,可以使用其中任何一种方式 - 将副本保存到主机并更正路径以适应你的环境。

将数组名称从http更改为ssl,并在本地添加证书使其正常工作,谢谢。请查看我的下一个问题,关于如何通过POST请求传递参数... http://stackoverflow.com/questions/33856354/google-recaptcha-missing-input-response-missing-input-secret - Ilario Engler

3

file_get_contents 替换为 curl。以下是代码:

更改 -

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

对于这段代码:

$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*/

请注意,$secret是存储在服务器端的密钥,$response是从前端通过post发送的recaptcha响应。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接