尝试实施新的 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 >
$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
出于某种原因,这个实现应该很简单,但我似乎做不好。
我已经在表单中实现了。这是 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 >
$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