Google Recaptcha v3 示例演示
Posted
技术标签:
【中文标题】Google Recaptcha v3 示例演示【英文标题】:Google Recaptcha v3 example demo 【发布时间】:2019-01-01 14:40:52 【问题描述】:到目前为止,我一直在使用 Google Recaptcha v2,但现在我想使用最新版本 (v3) 更新我的 WebApp。
任何人都可以为基本表单添加一个完全正常工作的 Google Recaptcha v3 示例,因为我找不到它的任何工作演示吗?
非常感谢。
非常感谢。
PS:我在服务器端使用 Java Servlets,但你解释使用 php 还是什么都没关系。
【问题讨论】:
这里是链接:recaptcha-demo.appspot.com 只需请求 v3 的分数,它就会以 JSON 形式返回响应 我创建了一个演示,但这是在 PHP 中访问我的博客link 但是我怎样才能放入 div 呢? @FreddySidauruk 您不要放入 div,它是通过调用 google api 的 javascript 函数执行的,然后会像 recaptchav2 一样为您提供响应。 我在这里发布了一个简单但详细的纯 JS 和 PHP 演示:***.com/questions/50405977/… 【参考方案1】:实现 ReCaptcha v3 的简单代码
基本的JS代码
<script src="https://www.google.com/recaptcha/api.js?render=your reCAPTCHA site key here"></script>
<script>
grecaptcha.ready(function()
// do request for recaptcha token
// response is promise with passed token
grecaptcha.execute('your reCAPTCHA site key here', action:'validate_captcha')
.then(function(token)
// add token value to form
document.getElementById('g-recaptcha-response').value = token;
);
);
</script>
基本的 html 代码
<form id="form_id" method="post" action="your_action.php">
<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
<input type="hidden" name="action" value="validate_captcha">
.... your fields
</form>
基本的 PHP 代码
if (isset($_POST['g-recaptcha-response']))
$captcha = $_POST['g-recaptcha-response'];
else
$captcha = false;
if (!$captcha)
//Do something with error
else
$secret = 'Your secret key here';
$response = file_get_contents(
"https://www.google.com/recaptcha/api/siteverify?secret=" . $secret . "&response=" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']
);
// use json_decode to extract json response
$response = json_decode($response);
if ($response->success === false)
//Do something with error
//... The Captcha is valid you can continue with the rest of your code
//... Add code to filter access using $response . score
if ($response->success==true && $response->score <= 0.5)
//Do something to denied access
您必须使用 $response.score 的值过滤访问。它的取值范围为 0.0 到 1.0,其中 1.0 表示用户与您的网站的最佳交互,0.0 表示最差的交互(如机器人)。您可以在ReCaptcha documentation 中看到一些使用示例。
【讨论】:
您发布的代码没有检查score
字段的值;如果我正确理解了docs,success
仅表示发布的请求是否有效;有关交互的实际信息(即合法与否)包含在 score
字段中。
它在文档中:Note: reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action.
但是,一旦加载了库,您就会调用 execute。我会解决的。
人们不得不怀疑,为什么他们要求开发人员将密钥传递两次。
@Adam - 谷歌有没有关于这是否会对某些用户的分数产生负面影响的指导?想象一下,如果用户离开几个小时然后回来填写表格。同一个用户会在同一个浏览会话中请求超过 100 个令牌。
我想知道这样一个糟糕的例子怎么会有这么多赞成票。【参考方案2】:
我假设您已准备好站点密钥和密码。按照这个步骤。
在您的 HTML 文件中,添加脚本。
<script src="https://www.google.com/recaptcha/api.js?render=put your site key here"></script>
此外,请务必使用 jQuery 来轻松处理事件。
这是简单的表格。
<form id="comment_form" action="form.php" method="post" >
<input type="email" name="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>
</form>
您需要初始化 Google recaptcha 并监听 ready 事件。这是如何做到这一点的。
<script>
// when form is submit
$('#comment_form').submit(function()
// we stoped it
event.preventDefault();
var email = $('#email').val();
var comment = $("#comment").val();
// needs for recaptacha ready
grecaptcha.ready(function()
// do request for recaptcha token
// response is promise with passed token
grecaptcha.execute('put your site key here', action: 'create_comment').then(function(token)
// add token to form
$('#comment_form').prepend('<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
$.post("form.php",email: email, comment: comment, token: token, function(result)
console.log(result);
if(result.success)
alert('Thanks for posting comment.')
else
alert('You are spammer ! Get the @$%K out.')
);
);
);
);
</script>
这是示例 PHP 文件。您可以使用 Servlet 或 Node 或任何后端语言来代替它。
<?php
$email;$comment;$captcha;
if(isset($_POST['email']))
$email=$_POST['email'];
if(isset($_POST['comment']))
$comment=$_POST['comment'];
if(isset($_POST['token']))
$captcha=$_POST['token'];
if(!$captcha)
echo '<h2>Please check the the captcha form.</h2>';
exit;
$secretKey = "put your secret key here";
$ip = $_SERVER['REMOTE_ADDR'];
// post request to server
$url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($secretKey) . '&response=' . urlencode($captcha);
$response = file_get_contents($url);
$responseKeys = json_decode($response,true);
header('Content-type: application/json');
if($responseKeys["success"])
echo json_encode(array('success' => 'true'));
else
echo json_encode(array('success' => 'false'));
?>
这里是教程链接:https://codeforgeek.com/2019/02/google-recaptcha-v3-tutorial/
希望对你有帮助。
【讨论】:
这是错误的,没有考虑到 v3 中需要的分数。不要遵循本指南,请在链接页面上的 cmets 中阅读。 在几个答案(包括这个)都没有成功之后,我更幸运的是this answer。【参考方案3】:我们使用recaptcha-V3 仅用于查看网站流量质量,并将其用作非阻塞。 由于recaptcha-V3 不需要在现场显示并且可以用作隐藏,但您有显示验证码隐私等链接(推荐)
头部中的脚本标记
<script src="https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallbackV3&render='SITE KEY' async defer></script>
注意:“async defer”确保它是非阻塞的,这是我们的具体要求
JS 代码:
<script>
ReCaptchaCallbackV3 = function()
grecaptcha.ready(function()
grecaptcha.execute("SITE KEY").then(function(token)
$.ajax(
type: "POST",
url: `https://api.$window.appInfo.siteDomain/v1/recaptcha/score`,
data:
"token" : token,
,
success: function(data)
if(data.response.success)
window.recaptchaScore = data.response.score;
console.log('user score ' + data.response.score)
,
error: function()
console.log('error while getting google recaptcha score!')
);
);
);
;
</script>
HTML/Css 代码:
there is no html code since our requirement is just to get score and don't want to show recaptcha badge.
后端 - Laravel 代码:
Route:
Route::post('/recaptcha/score', 'Api\\ReCaptcha\\RecaptchaScore@index');
Class:
class RecaptchaScore extends Controller
public function index(Request $request)
$score = null;
$response = (new Client())->request('post', 'https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'response' => $request->get('token'),
'secret' => 'SECRET HERE',
],
]);
$score = json_decode($response->getBody()->getContents(), true);
if (!$score['success'])
Log::warning('Google ReCaptcha Score', [
'class' => __CLASS__,
'message' => json_encode($score['error-codes']),
]);
return [
'response' => $score,
];
我们得到分数并保存在我们以后提交表单时使用的变量中。
参考: https://developers.google.com/recaptcha/docs/v3 https://developers.google.com/recaptcha/
【讨论】:
在几个答案(包括这个)都没有成功之后,我更幸运的是this answer。 @ashleedawg 抱歉,如果这对您不起作用!我刚刚再次测试,看起来一切都很好!如果您使用我提到的为#Laravel 编写的 colutin,您的参考是简单的 php 实现,但如果您只是使用 RecaptchaScore 类,它也应该可以工作。【参考方案4】:我认为使用 Bootstrap 4 形式的 PHP 中功能齐全的 reCaptcha v3 示例演示可能对某些人有用。
引用显示的依赖项,交换您的电子邮件地址和密钥(创建您自己的密钥here),然后表单就可以测试和使用了。我编写了代码 cmets 以更好地阐明逻辑,还包括注释掉的控制台日志和 print_r 行,以便快速查看验证令牌和从 Google 生成的数据。
包含的 jQuery 函数是可选的,但它确实在此演示中创建了更好的用户提示体验。
PHP 文件 (mail.php
):
在注明的位置添加密钥(2 个位置)和电子邮件地址。
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST")
# BEGIN Setting reCaptcha v3 validation data
$url = "https://www.google.com/recaptcha/api/siteverify";
$data = [
'secret' => "your-secret-key-here",
'response' => $_POST['token'],
'remoteip' => $_SERVER['REMOTE_ADDR']
];
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
# Creates and returns stream context with options supplied in options preset
$context = stream_context_create($options);
# file_get_contents() is the preferred way to read the contents of a file into a string
$response = file_get_contents($url, false, $context);
# Takes a JSON encoded string and converts it into a PHP variable
$res = json_decode($response, true);
# END setting reCaptcha v3 validation data
// print_r($response);
# Post form OR output alert and bypass post if false. NOTE: score conditional is optional
# since the successful score default is set at >= 0.5 by Google. Some developers want to
# be able to control score result conditions, so I included that in this example.
if ($res['success'] == true && $res['score'] >= 0.5)
# Recipient email
$mail_to = "youremail@domain.com";
# Sender form data
$subject = trim($_POST["subject"]);
$name = str_replace(array("\r","\n"),array(" "," ") , strip_tags(trim($_POST["name"])));
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$phone = trim($_POST["phone"]);
$message = trim($_POST["message"]);
if (empty($name) OR !filter_var($email, FILTER_VALIDATE_EMAIL) OR empty($phone) OR empty($subject) OR empty($message))
# Set a 400 (bad request) response code and exit
http_response_code(400);
echo '<p class="alert-warning">Please complete the form and try again.</p>';
exit;
# Mail content
$content = "Name: $name\n";
$content .= "Email: $email\n\n";
$content .= "Phone: $phone\n";
$content .= "Message:\n$message\n";
# Email headers
$headers = "From: $name <$email>";
# Send the email
$success = mail($mail_to, $subject, $content, $headers);
if ($success)
# Set a 200 (okay) response code
http_response_code(200);
echo '<p class="alert alert-success">Thank You! Your message has been successfully sent.</p>';
else
# Set a 500 (internal server error) response code
http_response_code(500);
echo '<p class="alert alert-warning">Something went wrong, your message could not be sent.</p>';
else
echo '<div class="alert alert-danger">
Error! The security token has expired or you are a bot.
</div>';
else
# Not a POST request, set a 403 (forbidden) response code
http_response_code(403);
echo '<p class="alert-warning">There was a problem with your submission, please try again.</p>';
?>
HTML <head>
引导 CSS 依赖和 reCaptcha 客户端验证
放置在<head>
标签之间 - 将您自己的站点密钥粘贴到注明的位置。
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://www.google.com/recaptcha/api.js?render=your-site-key-here"></script>
HTML <body>
放在<body>
标签之间。
<!-- contact form demo container -->
<section style="margin: 50px 20px;">
<div style="max-width: 768px; margin: auto;">
<!-- contact form -->
<div class="card">
<h2 class="card-header">Contact Form</h2>
<div class="card-body">
<form class="contact_form" method="post" action="mail.php">
<!-- form fields -->
<div class="row">
<div class="col-md-6 form-group">
<input name="name" type="text" class="form-control" placeholder="Name" required>
</div>
<div class="col-md-6 form-group">
<input name="email" type="email" class="form-control" placeholder="Email" required>
</div>
<div class="col-md-6 form-group">
<input name="phone" type="text" class="form-control" placeholder="Phone" required>
</div>
<div class="col-md-6 form-group">
<input name="subject" type="text" class="form-control" placeholder="Subject" required>
</div>
<div class="col-12 form-group">
<textarea name="message" class="form-control" rows="5" placeholder="Message" required></textarea>
</div>
<!-- form message prompt -->
<div class="row">
<div class="col-12">
<div class="contact_msg" style="display: none">
<p>Your message was sent.</p>
</div>
</div>
</div>
<div class="col-12">
<input type="submit" value="Submit Form" class="btn btn-success" name="post">
</div>
<!-- hidden reCaptcha token input -->
<input type="hidden" id="token" name="token">
</div>
</form>
</div>
</div>
</div>
</section>
<script>
grecaptcha.ready(function()
grecaptcha.execute('your-site-key-here', action: 'homepage').then(function(token)
// console.log(token);
document.getElementById("token").value = token;
);
// refresh token every minute to prevent expiration
setInterval(function()
grecaptcha.execute('your-site-key-here', action: 'homepage').then(function(token)
console.log( 'refreshed token:', token );
document.getElementById("token").value = token;
);
, 60000);
);
</script>
<!-- References for the optional jQuery function to enhance end-user prompts -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="form.js"></script>
用于增强用户体验的可选 jQuery 函数 (form.js
):
(function ($)
'use strict';
var form = $('.contact_form'),
message = $('.contact_msg'),
form_data;
// Success function
function done_func(response)
message.fadeIn()
message.html(response);
setTimeout(function ()
message.fadeOut();
, 10000);
form.find('input:not([type="submit"]), textarea').val('');
// fail function
function fail_func(data)
message.fadeIn()
message.html(data.responseText);
setTimeout(function ()
message.fadeOut();
, 10000);
form.submit(function (e)
e.preventDefault();
form_data = $(this).serialize();
$.ajax(
type: 'POST',
url: form.attr('action'),
data: form_data
)
.done(done_func)
.fail(fail_func);
); )(jQuery);
【讨论】:
非常彻底;在放弃其他(得分较高的)答案后,我很快就开始工作了。谢谢! 注意:“reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action rather than on page load.
”(src) 这在评论表单中尤为重要——我作为实时网站的用户曾遇到过这种情况,在输入详细的(冗长的)愤怒反馈后,然后网站的表格不允许我提交。这可能非常令人沮丧!
@ashleedawg 已编辑为包含每 60 秒刷新一次的令牌
@TalkNerdyToMe 请原谅我的无知,您在代码的哪一部分每 60 秒刷新一次令牌?
@Albert 一点也不无知 - 我提交的编辑似乎被拒绝了。我想SO只会让你知道编辑何时被接受??那个编辑真的会有所帮助,所以我不知道为什么它会被扔掉。我已经再次提交了修改,希望这次不会被拒绝,如果是,我会尽力解释。【参考方案5】:
如果您是在您的网站上新实施 recaptcha,我建议添加 api.js 并让谷歌在 1-2 天内收集您用户的行为数据。这种方式非常安全,尤其是在开始使用 score 之前。
【讨论】:
欢迎来到 SO!更多信息或链接会有所帮助。 (查看How to Answer。)【参考方案6】:我看过大多数不能正常工作的文章,这就是为什么新开发人员和专业开发人员对此感到困惑的原因。
我正在以非常简单的方式向您解释。在这段代码中,我每隔 3 秒的时间间隔在客户端生成一个 google Recaptcha 令牌,因为该令牌仅在几分钟内有效,这就是为什么如果任何用户花时间填写表格,那么它可能会过期。
首先我有一个 index.php 文件,我将在其中编写 HTML 和 JavaScript 代码。
<!DOCTYPE html>
<html>
<head>
<title>Google Recaptcha V3</title>
</head>
<body>
<h1>Google Recaptcha V3</h1>
<form action="recaptcha.php" method="post">
<label>Name</label>
<input type="text" name="name" id="name">
<input type="hidden" name="token" id="token" />
<input type="hidden" name="action" id="action" />
<input type="submit" name="submit">
</form>
<script src="https://www.google.com/recaptcha/api.js?render=put your site key here"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
setInterval(function()
grecaptcha.ready(function()
grecaptcha.execute('put your site key here', action: 'application_form').then(function(token)
$('#token').val(token);
$('#action').val('application_form');
);
);
, 3000);
);
</script>
</body>
</html>
接下来,我创建了 recaptcha.php 文件在服务器端执行它
<?php
if ($_POST['submit'])
$name = $_POST['name'];
$token = $_POST['token'];
$action = $_POST['action'];
$curlData = array(
'secret' => 'put your secret key here',
'response' => $token
);
$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, http_build_query($curlData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$curlResponse = curl_exec($ch);
$captchaResponse = json_decode($curlResponse, true);
if ($captchaResponse['success'] == '1' && $captchaResponse['action'] == $action && $captchaResponse['score'] >= 0.5 && $captchaResponse['hostname'] == $_SERVER['SERVER_NAME'])
echo 'Form Submitted Successfully';
else
echo 'You are not a human';
此代码的来源。如果您想了解此代码的解释,请访问。 Google reCAPTCHA V3 integration in PHP
【讨论】:
我同意你的第一句话......这对我也不起作用。 (“You are not a human
”)。唯一对我有用的答案是this。
嗨@clayray,我已经在代码中应用了分数。
啊,是的,所以你有@SumitKumarGupta。抱歉,我将删除我的评论。
这对我有用。站点密钥有两个地方,秘密有一个地方。不要错过那些家伙【参考方案7】:
我通过 Angular ajax 调用在 PHP 上处理 POST。我也喜欢看谷歌的分数。
这对我很有效...
$postData = json_decode(file_get_contents('php://input'), true); //get data sent via post
$captcha = $postData['g-recaptcha-response'];
header('Content-Type: application/json');
if($captcha === '')
//Do something with error
echo ' "status" : "bad", "score" : "none"';
else
$secret = 'your-secret-key';
$response = file_get_contents(
"https://www.google.com/recaptcha/api/siteverify?secret=" . $secret . "&response=" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']
);
// use json_decode to extract json response
$response = json_decode($response);
if ($response->success === false)
//Do something with error
echo ' "status" : "bad", "score" : "none"';
else if ($response->success==true && $response->score <= 0.5)
echo ' "status" : "bad", "score" : "'.$response->score.'"';
else
echo ' "status" : "ok", "score" : "'.$response->score.'"';
在 HTML 上
<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
关于js
$scope.grabCaptchaV3=function()
var myCaptcha = angular.element('#g-recaptcha-response').val();
var params =
method: 'POST',
url: 'api/recaptcha.php',
headers:
'Content-Type': undefined
,
data: 'g-recaptcha-response' : myCaptcha
$http(params).then(function(result)
console.log(result.data);
, function(response)
console.log(response.statusText);
);
【讨论】:
【参考方案8】:对于“基本形式”(如原始问题所要求的那样),如果您满足在服务器上进行验证,那么所需要的很简单。这是一个完整的 HTML 页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://www.google.com/recaptcha/api.js"></script>
<script>
<!--
function onSubmit()
var form = document.forms[0];
if ( form['name'].value )
form.submit();
else
alert( 'Please provide a name.' );
//-->
</script>
</head>
<body>
<form action="process.asp" method="post">
Name: <input type="text" name="name" /><br /><br />
<button class="g-recaptcha" data-sitekey="SITE_KEY" data-callback='onSubmit' data-action='contact'>Send</button>
</form>
</body>
</html>
这是处理它的完整页面,为简单起见,使用 Classic ASP (filename = process.asp):
<%@ Language=JavaScript %>
<%
var name = Request( 'name' ).Item;
var recaptchaResponse = Request( 'g-recaptcha-response' ).Item;
var ip = Request.ServerVariables( 'REMOTE_ADDR' );
var xmlhttp = Server.CreateObject( 'MSXML2.ServerXMLHTTP' );
var query = 'secret=SECRET_KEY&response=' + recaptchaResponse + '&remoteip=' + ip;
xmlhttp.open( 'POST', 'https://www.google.com/recaptcha/api/siteverify?' + query, false ); // false says to wait for response
xmlhttp.send();
var response = JSON.parse( xmlhttp.responseText );
Response.Write( name + ' is a ' + (response.success && response.action == 'contact' && response.score > 0.5 ? 'HUMAN' : 'ROBOT') );
%>
几点说明:
-
您将提供自己的 SITE_KEY 和 SECRET_KEY。
您需要一个 JSON 解析器。
您将使用适合您的方法进行服务器端 POST
服务器。
我添加了一个简单的表单字段验证,以便您了解如何
整合它。
您可以任意设置“action”字符串,但请确保
服务器上的内容与 HTML 中的内容一致。
您可能希望对 response.success 做出不同的响应
不正确或 response.action 与您的操作不匹配
字符串,或进行其他错误检查。
您可能需要 "> 0.5" 以外的条件分数。
此代码与两分钟超时没有问题。
【讨论】:
以上是关于Google Recaptcha v3 示例演示的主要内容,如果未能解决你的问题,请参考以下文章
Google reCaptcha v3 与 google reCaptcha Enterprise