尝试实施新的 Google 验证码

Trying to implement the new Google CAPTCHA

出于某种原因,这个实现应该很简单,但我似乎做不好。

我已经在表单中实现了。这是 link 但表单仍会在未验证验证码的情况下提交。这是我完成验证码验证的表单处理页面。

如果有人能帮我解决这个问题,我将不胜感激。

 <?php
 require_once('../Connections/conn.php'); 

// session_start();

// captcha validation
if(isset($_POST['submit'])){

$url="https://www.google.com/recaptcha/api/siteverify";
$privatekey='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$response = file_get_contents($url."?secret=".$privatekey."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']);

$data= json_decode($response);

}




?>


<!DOCTYPE html>
<!--[if (gte IE 9)|!(IE)]><!-->
<html lang="en">
<!--<![endif]-->
<head>

   <!-- Basic Page Needs
   ================================================== -->
   <meta charset="utf-8">
   <title>WOWSERVICE NIGERIA</title>
   <meta name="description" content="Extent - another WordPress theme">
   <meta name="author" content="Webnus">

   <!-- Mobile Specific Metas
   ================================================== -->
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

   <!-- CSS
   ================================================== -->
   <link rel="stylesheet" href="../css/style.css" type="text/css">
<link rel="stylesheet" href="../css/bootstrap.min.css" type="text/css">


<!-- <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:300italic,400italic,400,300,600,700,900|Varela|Arapey:400,400italic' rel="stylesheet" type='text/css' >-->

   <!-- JS
   ================================================== -->
   <script src="js/jquery.min.js" type="text/javascript"></script>
   <script src="layerslider/js/greensock.js" type="text/javascript"></script>
   <script src="SpryAssets/SpryValidationTextField.js" type="text/javascript"></script>
   <script src="SpryAssets/SpryValidationSelect.js" type="text/javascript"></script>
     <link rel="stylesheet" href="css/datepicker.css">




<!--[if lt IE 9]>
   <script src="../js/modernizr.custom.11889.js" type="text/javascript"></script>
   <script src="../js/respond.js" type="text/javascript"></script>
   <![endif]-->
   <!-- HTML5 Shiv events (end)-->
   <!-- MEGA MENU -->

   <!-- Favicons
   ================================================== -->
   <link rel="shortcut icon" href="images/favicon.ico">
   <link href="SpryAssets/SpryValidationTextField.css" rel="stylesheet" type="text/css">
   <link href="SpryAssets/SpryValidationSelect.css" rel="stylesheet" type="text/css">
</head>
<body class="yakisoba yakisoba-home">

<!-- Primary Page Layout
================================================== -->
<div id="wrap" class="boxed-wrap">

   <!-- Top Bar -->
   <section class="top-bar">
      <div class="container">
         <div class="top-links lftflot">
         <a href="#">About</a>
          <a href="#">Articles</a>
          <a href="#">Service News</a>
           <a href="#">Survey</a>
            <a href="#">Contact</a>
         </div>
         <div class="socialfollow rgtflot"><a href="" class="facebook"><i class="fa-facebook"></i></a><a href="" class="twitter"><i class="fa-twitter"></i></a><a href="" class="vimeo"><i class="fa-vimeo-square"></i></a></div>
     </div>
   </section> <!-- end top-bar -->

   <header id="header"  class="horizontal-w sm-rgt-mn">
      <div  class="container">
         <div class="col-md-7 col-sm-6 logo-wrap">
            <div class="logo">
               <a href="home.php"><img src="../images/logo.png" width="170" id="img-logo-w1" alt="logo" class="img-logo-w1"></a>
               <a href="home.php"><img src="../images/logo.png" width="130" id="img-logo-w2" alt="logo" class="img-logo-w2"></a>
            </div> <!-- end logo -->
         </div> <!-- end col-md-7 -->
         <div class="col-md-5 col-sm-6 alignright">
            <hr class="vertical-space" />
            <div class="widget">
               <div class="webnus-ad">
                  <a href="#"><img src="../images/homes/adv.jpg" alt="" /></a>          
                  <div class="clear"></div>
               </div>
           </div> <!-- end widget -->
         </div> <!-- end col-md-5 -->
      </div> <!-- end container -->
      <hr class="vertical-space" />
      <nav id="nav-wrap" class="nav-wrap2  mn4 darknavi">
         <div class="container">
            <ul id="nav">
               <li><a href="../post_complaint.php">Post Complaints</a></li>
               <li><a href="../post_commendation.php">Post Commendation</a></li>
               <li><a href="../request_report.php">Request for Report</a></li>
               <li><a href="../contact_details_upload.php">Upload Contact Details</a></li>
          <!--     <li><a href="#">Travel</a></li>-->
            </ul>
         </div> 
        <!-- end container -->
      </nav> <!-- nav wrap -->
   </header> <!-- end header -->
  <p></br></p>

    <div class="row">
        <div class="col-md-1"></div>

        <div class="col-md-10">

        <div class="bg-primary">

     <?php

     // if validation is successfull

     if(isset($data->success) AND $data->success==true){



       $query = $_POST['query']; 
    // gets value sent over search form

    $min_length = 3;
    // you can set minimum length of the query if you want

    if(strlen($query) >= $min_length){ // if query length is more or equal minimum length then

        $query = htmlspecialchars($query); 
        // changes characters used in html to their equivalents, for example: < to &gt;

        $query = mysql_real_escape_string($query);
        // makes sure nobody uses SQL injection

        $raw_results = mysql_query("SELECT * FROM request_report
            WHERE (`ticket` LIKE '%".$query."%')") or die(mysql_error());



        // * means that it selects all fields, you can also write: `id`, `title`, `text`
        // articles is the name of our table

        // '%$query%' is what we're looking for, % means anything, for example if $query is Hello
        // it will match "hello", "Hello man", "gogohello", if you want exact match use `title`='$query'
        // or if you want to match just full word so "gogohello" is out use '% $query %' ...OR ... '$query %' ... OR ... '% $query'

        if(mysql_num_rows($raw_results) > 0){ // if one or more rows are returned do following

            while($results = mysql_fetch_array($raw_results)){
            // $results = mysql_fetch_array($raw_results) puts data from database into array, while it's valid it does the loop
             if($results ['status']=='0'){
                echo "<p> The request associated with ticket number  <strong>" .$results['ticket']."</strong> is still being processed....</p>";
                // posts results gotten from database(title and text) you can also show id ($results['id'])
                }

                else if ($results ['status']=='1'){

                echo "<p> The request associated with ticket number  <strong>" .$results['ticket']."</strong> has been processed and closed....</p>";
                // posts results gotten from database(title and text) you can also show id ($results['id'])

                }
            }

        }
        else{ // if there is no matching rows do following
            echo "Sorry no results found <br>";
        }

    }
    else{ // if query length is less than minimum
        echo "Ticket number should be within  ".$min_length;
    }




    //retrieving data from complaints table



}
else{

$msg="Please re-enter your reCAPTCHA.";

}   
?>

the form still submits without validating the captcha

表单提交其中的任何内容。如果 $_POST['g-recaptcha-response'] 来自未解决/{错误解决} 验证码,那么在服务器端当您验证站点 https://www.google.com/recaptcha/api/siteverify?... 时,您会得到响应。喜欢 {success:false}。这就是验证码无效的证明;因此实际上对于网站所有者(您)来说,验证码是在服务器端验证的。 查看更多 here.

我希望以下内容会有所帮助,我已经从我自己的示例中删除了代码,但确实有效。

On the page that has the captcha requirement
--------------------------------------------

head
----
<script type='text/javascript'>
    function verifyCaptcha(){
        /* 'grc' is the id of the placeholder DIV */
        grecaptcha.render( 'grc', {
            'sitekey'   :   'aaabbbcccdddeeefff-not-secret-key',
            'theme'     :   'light',
            'size'      :   'compact'
});
    }
</script>
<script src='https://www.google.com/recaptcha/api.js?onload=verifyCaptcha&render=explicit' async defer></script>



body
----
<form name='mailtest' method='post' action='/test/target.php'>
    <input type='text' name='name' value='joe bloggs' placeholder='Please enter your name' required />

    <!-- empty placeholder for re-captcha: targeted in javascript function verifyCaptcha -->
    <div id='grc'></div>

    <input type="submit" value="Submit form" />
</form>






/test/target.php (ie: the form target )
---------------------------------------
$google_secret='xxx-yyy-zzz-some-very-long-secret-key';
if( $_SERVER['REQUEST_METHOD']=='POST' ){

    $captcha=isset( $_POST['g-recaptcha-response'] ) && !empty( $_POST['g-recaptcha-response'] ) ? $_POST['g-recaptcha-response'] : false;
    if( !!$captcha===false ) die('empty captcha');

    $url="https://www.google.com/recaptcha/api/siteverify?secret=".$google_secret."&response=".trim( $captcha )."&remoteip=".$_SERVER['REMOTE_ADDR'];
    $response=json_decode( file_get_contents( $url ) );

    if( $response->success ){
        /* Everything ok - proceed with processing  */
    } else {
        /* Verification failed, abandon request */
    }

}

在与表单相同的目录中创建一个 php 文件并将其命名为 getCurlData.php 并粘贴以下代码并保存

function getCurlData($url)
{
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
        curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16");
        $curlData = curl_exec($curl);
        curl_close($curl);
        return $curlData;
}

之后使用正确的密钥和站点密钥进行验证

 $recaptcha=$_POST['g-recaptcha-response'];

        if(!empty($recaptcha))
        {
        include("getCurlData.php");
        $google_url="https://www.google.com/recaptcha/api/siteverify";
        $secret='put your key here';
        $ip=$_SERVER['REMOTE_ADDR'];
        $url=$google_url."?   secret=".$secret."&response=".$recaptcha."&remoteip=".$ip;
        $res=getCurlData($url);
        $res= json_decode($res, true);
        }
        else
        {
            $err_catpcha="* Verification error";
        }

请注意此 div 是捕获代码将显示的位置

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

我认为您对 Google reCaptcha 的工作原理有点困惑——它不会阻止用户 POSTing 数据(用户可以轻松绕过这种东西),它用于允许服务器端代码检查用户是否是机器人。

这意味着您还必须在服务器端有一些东西来检查提交的内容。你不能只在客户端做这一切。 (尽管看起来 Google 正在客户端执行所有操作,但 reCaptcha 按钮实际上位于另一台服务器上的 iframe 中。)

例如。在此处查看 Google 的演示:https://www.google.com/recaptcha/api2/demo

请注意,当您单击“提交”时,它仍然 POST 将数据传回服务器——服务器会响应您是否是人类。

正如 Google 的文档所述:

When your users submit the form where you integrated reCAPTCHA, you'll get as part of the payload a string with the name "g-recaptcha-response". In order to check whether Google has verified that user, send a POST request with these parameters:

URL: https://www.google.com/recaptcha/api/siteverify

secret (required) xxx
response (required) The value of 'g-recaptcha-response'.
remoteip The end user's ip address.

您基本上需要检查 POST 请求 secret 是否与您的 Recaptcha 帐户中的密钥匹配。如果是,那么你应该给用户一个下载link,如果不是,return一个错误信息。

您可以在 reCaptcha 文档中了解有关此过程的更多信息:https://developers.google.com/recaptcha/docs/verify


仅客户端

如果您不关心有人能够伪造结果,并且想阻止用户在不尝试通过验证码的情况下提交,您可以使用 jQuery 来做到这一点,如下所示:JSFiddle