【问题标题】:Integrating google reCaptcha into an existing payment form将 google reCaptcha 集成到现有的支付表单中
【发布时间】:2014-11-25 11:58:52
【问题描述】:

最近我的网站收到了大量通过我的付款表单发送的垃圾邮件,我决定需要添加 captcha 以防止这种情况发生。

我正在考虑几个选项,我决定使用 Google 的 reCaptcha。它似乎很容易设置和使用,但我遇到了一些问题。

首先我在表单的标题中包含了这个script

<script src='https://www.google.com/recaptcha/api.js'></script>

然后我在表单的底部添加了实际的 captcha 本身:

<div class="g-recaptcha" data-sitekey="6LdOVv4SAAAAAJ4muJvo_vD7vsd9T9QIfkEwcO7y"></div>

当我提交表单时,我会执行以下操作:

$captcha = $_POST["g-recaptcha-response"]; //Get Captcha token
$secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //Get Secret key
$google_response = http_get("https://www.google.com/recaptcha/api/siteverify", array("secret"=>$secret, "response"=>$captcha), $info); //perform Get request
print_r($info);

但是什么都没有发生,事实上,以前可以工作的页面只是挂起,甚至没有显示错误消息。有什么想法我可能做错了吗?根据我对文档的理解,响应将在JSON 中,成功将是真或假,如果为真,我想继续付款,如果为假,我想停止并返回表单。

非常感谢任何帮助。或者,如果有人有添加验证码的替代解决方案,我愿意研究一下。

【问题讨论】:

    标签: php forms captcha recaptcha


    【解决方案1】:

    试试这个运行 google new recaptcha 2015:

    ==PHP Verification==
    if(isset($_POST['submit'])){
        $userIP = $_SERVER["REMOTE_ADDR"];
        $recaptchaResponse = $_POST['g-recaptcha-response'];
        $secretKey = "SECRET_KEY";
        $request = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$secretKey}&response={$recaptchaResponse}&remoteip={$userIP}");
    
        if(!strstr($request, "true")){
            echo "NOPE (Failed Verification)";
        }
        else{
            echo "YUP (Successful Verification)";
        }
    }
    

    【讨论】:

    • 无法将响应轻松解析回 PHP 数组或 JSON 对象,这很烦人。
    • @NicholasPickering 如果您使用 Composer,Guzzle 是一个不错的软件包。
    • Google 本身建议仅使用 POST-Requests 进行验证。如果 google 不阻止多个秘密参数,您的方法很容易受到用户提供类似“token&secret=SecretOfAnotherRecaptchaAccount”作为 g-recaptcha-response 的影响。这意味着用户可以使用任何有效的 recaptcha 令牌进行验证,这很糟糕。最好使用 curl 和 post 请求。
    【解决方案2】:

    不要使用 file_get_contents。 Google recommends to use POST-Requests 调用他们的 api。像上面这样的 GET 请求可能会导致多个问题:

    • 由于安全原因,可能会阻止调用 url (allow_url_fopen)
    • 用户可能会将 someToken&secret=otherSitesSecret 作为输入传递给您的 $_POST[g-recaptcha-response]。如果您只是将调用的 url 字符串连接起来,您将向 Google 传递另一个秘密。然后,用户可以使用从任何站点获得的任何重新验证响应来验证自己。这是一个安全问题。
    • Google 返回的令牌可能很长。 Web 服务器仅支持 url 中的几千个字符。这可能会导致字符串被截断,并且您将收到有效输入错误。

    因此,使用类似的东西

    // Get resource
    $curl = curl_init();
    
    // Configure options, incl. post-variables to send.
    curl_setopt_array($curl, array(
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => 'https://www.google.com/recaptcha/api/siteverify',
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => array(
            'secret' => 'your_secret_code_here',
            'response' => $_POST['g-recaptcha-response']
        )
    ));
    
    // Send request. Due to CURLOPT_RETURNTRANSFER, this will return reply as string.
    $resp = curl_exec($curl);
    
    // Free resources.
    curl_close($curl);
    
    // Validate response
    if(strpos($resp, '"success": true') !== FALSE) {
        echo "Verified.";
    } else {
        echo "Not verified.";
    }
    

    此外,验证部分在接受为“已验证”的内容方面更为保守。

    【讨论】:

    • 根据this thread,如果您没有用于通话的 SSL 证书,您需要在数组中添加CURLOPT_SSL_VERIFYPEER =&gt; 0(我想这不是实现安全性的最安全方式功能!)
    • 您为什么要这样做?谷歌总是为他们的 recaptcha api 使用有效的证书。如果没有验证,您的系统有问题。我还评论了您链接的答案,确实没有必要这样做。
    • 仅用于开发目的
    • (如果您没有设置 ssl 证书
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2019-12-26
    • 2021-03-25
    • 2014-09-16
    • 2020-02-02
    • 1970-01-01
    • 2021-05-16
    相关资源
    最近更新 更多