实施 reCAPTCHA V3
如果您正饱受网站或客户网站上的垃圾邮件和机器人提交的困扰,reCAPTCHA 就是您的解决方案。reCAPTCHA 由 Google 提供支持,能够抵御大多数机器人垃圾邮件。您可能之前已经使用过 reCAPTCHA,或者现在有兴趣使用它,但面对 v3 版本,您或许不知道该如何入手。
在本教程中,我们将从头到尾实现 reCAPTCHA V3,并使用 Vanilla JS 通过 fetch 验证和提交表单。
在 YouTube 上观看
注意:本教程使用 WAMP 作为服务器,因为我们需要使用 PHP 来处理邮件发送和 reCaptcha 验证。您也可以使用自己的服务器配置。我选择 WAMP 是因为它对大多数用户来说最容易上手。
文件夹结构
我们使用基本的 HTML 结构,并配合一个 PHP 文件来处理 reCaptcha 验证和发送电子邮件。您可以根据自己的喜好设置文件,但为了方便本教程的讲解,您可以参考我下面的示例。
index.html
thanks.html
send.php
/assets
/js
init.js
/sass
style.scss
/css (generated by Sass)
style.css
style.min.css
创建我们的表格
我们使用的是基本的 HTML 表单,没有使用任何处理器。我添加了 Bootstrap 来提升视觉效果,但这并非本教程的必需项。我还添加了对 Sass 生成的 style.min.css 文件的 CSS 引用。
在表单 HTML 中,您会看到表单元素及其错误信息(使用类名)invalid-feedback。请确保您已添加错误信息 div 元素,因为我们的 JS 代码依赖于它。此外,请确保将整个表单包裹在一个 div 元素中,formfields就像我在下面做的那样。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/style.min.css" rel="stylesheet">
<title>reCAPTCHA V3 Demo</title>
</head>
<body>
<div class="container">
<br>
<h1 class="text-center">reCAPTCHA V3 Demo</h1>
<br>
<form method="post" id="contact" class="contact">
<input type="hidden" name="recaptchaResponse" id="recaptchaResponse">
<div class="formfields">
<div class="row">
<div class="col-md-6">
<div class="form-element">
<input type="text" name="fname" id="fname" class="form-control form-control-lg" placeholder="First Name *">
<div class="invalid-feedback">
Please enter your first name.
</div>
</div>
<br>
</div>
<div class="col-md-6">
<div class="form-element">
<input type="text" name="lname" id="lname" class="form-control form-control-lg" placeholder="Last Name *">
<div class="invalid-feedback">
Please enter your last name.
</div>
</div>
<br>
</div>
</div>
<div class="form-element">
<input type="text" name="email" id="email" class="form-control form-control-lg" placeholder="Email Address *">
<div class="invalid-feedback">
Please enter your email address.
</div>
</div>
<br>
<div class="form-element">
<textarea name="message" id="message" cols="30" rows="10" class="form-control" placeholder="How can I help you? *"></textarea>
<div class="invalid-feedback">
Please enter a message.
</div>
</div>
<br>
<button type="submit" class="btn btn-lg btn-primary" id="submit-button">Send Message</button>
<br>
<br>
<p class="text-center">
<small>This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy">Privacy Policy</a> and <a href="https://policies.google.com/terms">Terms of Service</a> apply.</small>
</p>
</div>
<div id="alert" class="text-center"></div>
</form>
</div>
</body>
</html>
目前的HTML代码就这些了。如果您查看此页面,应该会看到一个标准表单。
JS验证
在本节中,我们将处理 JavaScript 验证以及错误或成功信息的显示。首先,我们加载 JavaScript,然后获取表单。表单提交后,我们遍历每个字段并逐一进行验证。如果某个字段为空,我们则显示错误信息并高亮显示该字段。如果字段有效,我们则用绿色边框高亮显示该字段。
所有字段验证无误后,我们将隐藏表单并显示等待消息。
window.addEventListener("load", function(){ // Wait for the page to load
"use strict"; // Strict mode for JavaScript
const form = document.querySelector(".contact") // Get the form
form.addEventListener("submit", function (event){
event.preventDefault() // Prevent the default action of the form
let fields = document.querySelectorAll(".contact .form-control") // Get all the fields
let valid = true
for (var i = 0; i < fields.length; i++) {
fields[i].classList.remove("no-error") // Remove the no-error class from all fields
if(fields[i].value === ""){ // If the field is empty
fields[i].classList.add("has-error")
fields[i].nextElementSibling.style.display = "block"
valid = false
}else{ // If the field is not empty
fields[i].classList.remove("has-error")
fields[i].classList.add("no-error")
fields[i].nextElementSibling.style.display = "none"
}
}
if(valid){ // If all the fields are valid
document.querySelector(".formfields").style.display = "none"
document.querySelector("#alert").innerText = "Processing your submission, please wait..."
}
})
})
在 HTML 代码主体之后,添加以下代码以引用您的 JS 文件:
<script src="/assets/js/init.js"></script>
如果你已经看到这里,那么你应该已经创建了一个可以验证输入内容但不会显示颜色的表单。接下来我们将使用 CSS 来实现这一点。
萨斯
CSS 样式是我喜欢的字段样式,您可以根据自己的喜好进行更改,也可以保留我的样式。
注意:我使用 Sass 编译 CSS,所以你需要一个类似VS Code 的Live Sass Compiler这样的 CSS 处理器。我已经设置好,它可以处理我的 Sass 文件,并在我的 CSS 文件夹中添加 style.css 和 style.min.css 文件。
body {
color:#333;
}
.form-control {
border-radius: 0px;
border: 1px solid #333;
&.form-control-lg {
height:calc(3.5rem + 2px);
padding:1rem 0.75rem;
font-size:1rem;
}
&::placeholder {
font-size:1rem
}
&.has-error {
border:1px solid red;
}
&.no-error {
border:1px solid green;
}
}
.error {
color:red;
}
.success {
color: green
}
.btn {
border-radius: 0;
border:0;
&.btn-primary {
background-color:#38a4ef;
&:hover {
background-color: #2786c9;
}
现在,如果您测试当前的代码,您应该会看到验证结果以及彩色错误消息或成功框。
创建您的 reCAPTCHA V3 密钥
登录或创建一个新的 Google reCAPTCHA 管理控制台帐户。您可以使用以下链接进行操作:https://www.google.com/recaptcha/admin
进入页面后,点击“+”号即可创建一个新的 reCAPTCHA V3 网站。请务必使用 reCAPTCHA V3 版本。填写完所有字段后即可开始。完成后,您应该会看到一个网站和一个私钥。如果没有看到,您可以打开您的网站,然后点击右上角的齿轮菜单图标。
在您的网站上添加 reCAPTCHA
在 HTML 代码中,紧接 init.js 引用上方,添加以下代码,并将替换yoursitekey为您上面提供的实际站点密钥:
<script src="https://www.google.com/recaptcha/api.js?render=yoursitekey"></script>
在你的 init.js 文件中,在以下代码行之后添加以下代码document.querySelector("#alert").innerText = "Processing your submission, please wait..."
yoursitekey请将上述内容替换为您实际的网站密钥。
grecaptcha.ready(function() { // Wait for the recaptcha to be ready
grecaptcha
.execute("yoursitekey", {
action: "contact"
}) // Execute the recaptcha
.then(function(token){
let recaptchaResponse = document.getElementById("recaptchaResponse")
recaptchaResponse.value = token // Set the recaptcha response
fetch("/send.php", {
method: "POST",
body: new FormData(form), // Send the form data
})
.then((response) => response.text())
.then((response) => {
const responseText = JSON.parse(response) // Get the response
if(responseText.error !== "") { // If there is an error
document.querySelector("#alert").innerText = responseText.error
document.querySelector("#alert").classList.add("error")
document.querySelector(".formfields").style.display = "block"
return
}
document.querySelector("#alert").innerText = responseText.success
document.querySelector("#alert").classList.add("success")
window.location.replace("/thanks") // Redirect to the thanks page
})
})
})
你新创建的完整JS文件应该如下所示:
window.addEventListener("load", function(){ // Wait for the page to load
"use strict"; // Strict mode for JavaScript
const form = document.querySelector(".contact") // Get the form
form.addEventListener("submit", function (event){
event.preventDefault() // Prevent the default action of the form
let fields = document.querySelectorAll(".contact .form-control") // Get all the fields
let valid = true
for (var i = 0; i < fields.length; i++) {
fields[i].classList.remove("no-error") // Remove the no-error class from all fields
if(fields[i].value === ""){ // If the field is empty
fields[i].classList.add("has-error")
fields[i].nextElementSibling.style.display = "block"
valid = false
}else{ // If the field is not empty
fields[i].classList.remove("has-error")
fields[i].classList.add("no-error")
fields[i].nextElementSibling.style.display = "none"
}
}
if(valid){ // If all the fields are valid
document.querySelector(".formfields").style.display = "none"
document.querySelector("#alert").innerText = "Processing your submission, please wait..."
grecaptcha.ready(function() { // Wait for the recaptcha to be ready
grecaptcha
.execute("yoursitekey", {
action: "contact"
}) // Execute the recaptcha
.then(function(token){
let recaptchaResponse = document.getElementById("recaptchaResponse")
recaptchaResponse.value = token // Set the recaptcha response
fetch("/send.php", {
method: "POST",
body: new FormData(form), // Send the form data
})
.then((response) => response.text())
.then((response) => {
const responseText = JSON.parse(response) // Get the response
if(responseText.error !== "") { // If there is an error
document.querySelector("#alert").innerText = responseText.error
document.querySelector("#alert").classList.add("error")
document.querySelector(".formfields").style.display = "block"
return
}
document.querySelector("#alert").innerText = responseText.success
document.querySelector("#alert").classList.add("success")
window.location.replace("/thanks") // Redirect to the thanks page
})
})
})
}
})
})
一旦您到达这里,我们就可以开始编写 send.php 文件,该文件将用于获取您的 reCAPTCHA 分数并处理您的表单。
表单验证并提交后,如果您在上面的结构中包含了 thanks.html 页面,它将重定向到该页面。
使用 PHP 验证 reCAPTCHA
为了确保网站安全,防止机器人和垃圾邮件的攻击,您需要访问 Google 的 API 服务器并验证发送的内容。Google 并未透露太多关于如何处理垃圾邮件请求的信息,但我们知道,得分高于 0.5 通常足以阻止垃圾邮件和机器人提交。因此,我们将根据该指标编写代码。
这个 PHP 文件会再次验证您是否已提交所需的表单元素,然后将这些元素与 Google 的 reCAPTCHA API 进行比对,并给出评分。获得评分后,您就可以处理您的电子邮件了。
注意:请将yoursecretkey上方所示的密钥替换为您实际的密钥。
<?php
/**
* Check to see if all fields that are required have been submitted
*
* @return boolean
*/
function isValid(){
if(
$_POST['fname'] != '' &&
$_POST['lname'] != '' &&
$_POST['email'] != '' &&
$_POST['message'] != ''
) {
return true;
}
return false;
}
// Declare variables to prepare for form submission
$success_output = '';
$error_output = '';
if (isValid()) {
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify'; // URL to the reCAPTCHA server
$recaptcha_secret = 'yoursecretkey'; // Secret key
$recaptcha_response = $_POST['recaptchaResponse']; // Response from reCAPTCHA server, added to the form during processing
$recaptcha = file_get_contents($recaptcha_url.'?secret='.$recaptcha_secret.'&response='.$recaptcha_response); // Send request to the server
$recaptcha = json_decode($recaptcha); // Decode the JSON response
if($recaptcha->success == true && $recaptcha->score >= 0.5 && $recaptcha->action == "contact"){ // If the response is valid
// run email send routine
$success_output = 'Your message was sent successfully.'; // Success message
}else{
$error_output = 'Something went wrong. Please try again later'; // Error message
}
}else{
$error_output = 'Please fill out all of the required fields.'; // Error message
}
// Output error or success message
$output = [
'error' => $error_output,
'success' => $success_output
];
// Return the output in JSON format
echo json_encode($output);
此 PHP 文件将返回一个 JSON 对象,该对象将在上面的 JS 文件中使用,以显示错误、显示成功或在本例中重定向到感谢页面。
注意:代码中已预留空间供您添加自己的邮件功能。标注方式如下:// run email send routine
删除该行代码并添加您的 PHP 邮件例程。通常情况下,代码会像这样mail($to, $subject, $message, $headers);。如果您需要帮助,可以访问 PHP 官网了解更多详情:https://www.php.net/manual/en/function.mail.php
最后一步
当您将 Google 的 V3 reCAPTCHA 添加到您的网站时,您会在右下角看到一个小徽章。如果您按照接下来的几个步骤操作,则无需显示此徽章,但您必须保留此徽章或显示一条提示信息。
在 HTML 代码中,将以下代码添加到按钮下方。
<br>
<br>
<p class="text-center">
<small>This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy">Privacy Policy</a> and <a href="https://policies.google.com/terms">Terms of Service</a> apply.</small>
</p>
现在你已经有了所需的消息,你可以将其添加到你的 Sass 文件中并移除徽章。
.grecaptcha-badge {
display:none;
}
结论
现在一切就绪,您可以刷新页面并测试表单。一切应该都能正常运行,您现在可以彻底摆脱机器人了。
文章来源:https://dev.to/thedevdrawer/implementing-recaptcha-v3-1mm6