php 挣扎于recaptcha v2和表单提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27264459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:16:33  来源:igfitidea点击:

Struggling with recaptcha v2 and form submission

phpjsonformsrecaptcha

提问by millsteedo

https://developers.google.com/recaptcha/docs/verify

https://developers.google.com/recaptcha/docs/verify

if(isset($_POST['submit'])){
$recaptchaResponse = $_POST['g-recaptcha-response'];
$secretKey = 'MYKEY';
$request = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$recaptchaResponse);

    if(!strstr($request,"false")){
echo '<div class="notification error clearfix"><p><strong>Attention!</strong> You didnt complete the captcha.</p></div>';
exit();

Then the rest of the php file mails the form, but its just sending anyway even if you dont complete the recaptcha. Basically if the JSON returns a false I was hoping the it wouldnt send and would display an error

然后 php 文件的其余部分通过邮件发送表单,但即使您没有完成 recaptcha,它也只是发送。基本上,如果 JSON 返回 false,我希望它不会发送并显示错误

Also here is the form from the page if it helps, Ive probably done something wrong there too...

如果有帮助的话,这里也是页面上的表格,我可能在那里也做错了什么......

<form method="POST" action="post.php" name="contactform" id="contactform" class="container">

            <fieldset>
                <div class="form-field grid-half">
                    <label for="name">Name</label>
                    <span><input type="text" name="name" id="name" /></span>
                </div>
                <div class="form-field grid-half">
                    <label for="email">Email</label>
                    <span><input type="email" name="email" id="email" /></span>
                </div>
                <div class="form-field grid-full">
                    <label for="message">Message</label>
                    <span><textarea name="message" id="message"></textarea></span>
                </div>                  
                <div class="form-field grid-full">
                        <div class="g-recaptcha" data-sitekey="MYKEY"></div>
                </div>
            </fieldset>
            <div class="form-click grid-full">
                <span><input type="submit" name="submit" value="Submit" id="submit" /></span>
            </div>

            <div id="alert" class="grid-full"></div>
        </form>     

回答by Alan Kael Ball

I found that sometimes, depending on the PHP version/config, accessing an object directly won't work, so use json_decode().

我发现有时候,根据 PHP 版本/配置,直接访问一个对象是行不通的,所以使用json_decode().

/* $response object returned from https://www.google.com/recaptcha/api/siteverify via which ever method you use */

$obj = json_decode($response);
if($obj->success == true)
{
    //passes test
}
else
{
    //error handling
}

回答by Peter

Using curlinstead of file_get_contents(should you, like me, want file_get_contentsto be disabled in the server settings)

使用curl而不是file_get_contents(如果你像我一样,想file_get_contents在服务器设置中被禁用)

$post_data = "secret=__your_secret_key__&response=".
   $_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR'] ;

$ch = curl_init();  
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, 
   array('Content-Type: application/x-www-form-urlencoded; charset=utf-8', 
   'Content-Length: ' . strlen($post_data)));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 
$googresp = curl_exec($ch);       
$decgoogresp = json_decode($googresp);
curl_close($ch);

if ($decgoogresp->success == true)
    {
    // Success
    }

回答by Elshan

Paste this snippet before the closing tag on your HTML template:

将此代码段粘贴到 HTML 模板的结束标记之前:

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

Paste this snippet at the end of the where you want the reCAPTCHA widget to appear:

将此代码段粘贴到您希望 reCAPTCHA 小部件出现的位置的末尾:

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

Example :

例子 :

<html>
  <head>
    <title>Google recapcha demo - Codeforgeek</title>
    <script src='https://www.google.com/recaptcha/api.js'></script>
  </head>
  <body>
    <h1>Google reCAPTHA Demo</h1>
    <form id="comment_form" action="form.php" method="post">
      <input type="email" placeholder="Type your email" size="40"><br><br>
      <textarea name="comment" rows="8" cols="39"></textarea><br><br>
      <input type="submit" name="submit" value="Post comment"><br><br>
       <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
    </form>
  </body>
</html>

form.php

表单.php

<?php

        $email;$comment;$captcha;
        if(isset($_POST['email'])){
          $email=$_POST['email'];
        }if(isset($_POST['comment'])){
          $email=$_POST['comment'];
        }if(isset($_POST['g-recaptcha-response'])){
          $captcha=$_POST['g-recaptcha-response'];
        }
        if(!$captcha){
          echo '<h2>Please check the the captcha form.</h2>';
          exit;
        }
        $response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=YOUR_SECRET_KEY&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
        if($response.success==true)            
        {
          echo '<h2>Thanks for posting comment.</h2>';
        }
?>

Sorce :

来源:

回答by Paul Ishak

First off, the answers already given here are absolutely adequate. That being said, I just wanted to include this function that wraps those answers into a slightly more convenient method, that way you can throw them into your function library and pretty much forget about it until google changes something. Enjoy!

首先,这里已经给出的答案是绝对足够的。话虽如此,我只是想包含这个函数,将这些答案包装成一个更方便的方法,这样你就可以将它们扔到你的函数库中,然后在谷歌改变某些东西之前几乎忘记它。享受!

//Put these two functions into your function library-------
function CaptchaVerify($apiSecret)
{
    //Returns -1 if no captcha response was in post(user did not submit form)
    //Returns 0 if the verification fails
    //Returns 1 if the verification succeeds
    $captcha = isset($_POST['g-recaptcha-response'])? "&response=".$_POST['g-recaptcha-response']:'';
    if($captcha != '')
    {
        $verifyUrl = "https://www.google.com/recaptcha/api/siteverify";
        $apiSecret = "?secret=".$apiSecret;
        $remoteip = "&remoteip=".$_SERVER['REMOTE_ADDR'];
        $response=file_get_contents($verifyUrl.$apiSecret.$captcha.$remoteip);
        $obj = json_decode($response);
        return (integer)$obj->success;          
    }
    return -1;
}
function MyCaptchaVerify()
{
    $apiSecret = "PUT YOUR CAPTCHA SECRET HERE";
    return CaptchaVerify($apiSecret);
}
//-------------------------------------------------------
//Example usage in your form
switch(MyCaptchaVerify())
{
    case -1:echo "The form has not been submitted yet(First Load).<br>";break;
    case  0:echo "The captcha verification failed.<br>";    break;
    case  1:echo "The captcha verification succeeded.<br>"; break;
}

回答by Surya

I prefer the cURL example to the file_get_contents as it gives more options for error logging and such. Some find cURL quite daunting though. For those users Guzzle is a very good alternative.

与 file_get_contents 相比,我更喜欢 cURL 示例,因为它为错误记录等提供了更多选项。不过,有些人发现 cURL 非常令人生畏。对于那些用户来说,Guzzle 是一个非常好的选择。

回答by Ariful Haque

If you want to use Curl PHP for getting response, you can use the following code:

如果要使用 Curl PHP 获取响应,可以使用以下代码:

  if(isset($_POST['submit'])){
     $privatekey = "paste_your_privatekey";
     $responseKey = $_POST["g-recaptcha-response"];
     $userIP = $_SERVER["REMOTE_ADDR"];

     /////Curl Start///////
     $ch = curl_init();

     curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
     curl_setopt($ch, CURLOPT_POST, 1);
     curl_setopt($ch, CURLOPT_POSTFIELDS, "secret=$privatekey&response=$responseKey&remoteip=$userIP");

     // Receive server response ...
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

     $server_output = curl_exec($ch);
     $response = json_decode($server_output);

     curl_close ($ch);
     /////Curl Close///////

     // Further processing ...
     if ($response->success == "true") {
        Success……..
     }esle{
        Failed…………….
     }
  }

回答by random

if (response == true) {
    mail();
} else {
    echo "error";
}