PbootCMS表单验证码集成与反垃圾机制:防止恶意提交
本文由广东鲸弘科技有限公司提供惠州小程序开发 / 网站建设专业分享。
在PbootCMS站点运营中,留言表单、联系表单、报名表单等各类交互表单,极易遭受机器人恶意提交、垃圾信息刷屏,不仅占用服务器资源,还会增加人工审核成本,甚至泄露站点信息。本文结合PbootCMS内置功能与二次开发,实现「验证码集成+多层反垃圾机制」,无需修改系统核心文件,适配PbootCMS V3.0及以上所有稳定版本,涵盖图形验证码、行为验证、后端过滤等多重防护,彻底解决恶意提交问题,代码均经过实测可直接复用。
核心逻辑:以「验证码验证」为第一道防线,拦截大部分机器人提交;以「行为验证+字段过滤」为第二道防线,区分真人与恶意提交;以「IP限制+提交频率控制」为第三道防线,拦截高频恶意请求;全程遵循PbootCMS开发规范,通过后台配置、前端渲染、后端验证的全流程管控,实现表单安全防护,兼顾安全性与用户体验。
一、开发前期准备
1.1 环境要求
PbootCMS版本:V3.0及以上(推荐V3.2.11及最新稳定版,内置验证码功能更完善,修复了旧版本验证码相关bug);
PHP环境:PHP 7.0+,需开启GD库(用于生成图形验证码,图形验证码渲染依赖该扩展);
开发权限:拥有PbootCMS后台管理员权限、服务器文件修改权限(用于编辑模板、添加自定义验证逻辑);
开发工具:文本编辑器(如VS Code)、浏览器开发者工具(用于调试验证码与表单提交逻辑);
基础认知:了解PbootCMS表单标签使用、模板文件结构,无需复杂PHP开发基础,可直接复用本文代码。
1.2 核心防护体系拆解
本文实现的反垃圾机制分为4层,层层递进,兼顾防护效果与用户体验,避免单一防护被绕过:
基础防护:集成PbootCMS内置图形验证码,拦截简单机器人提交,无需额外开发,配置即可使用;
行为防护:添加前端行为验证(如点击按钮倒计时、表单填写时长限制),区分真人与机器人操作;
内容防护:后端添加关键词过滤、空字段验证、隐藏字段陷阱,拦截垃圾信息与恶意提交;
高频防护:添加IP提交频率限制、同一IP单日提交次数限制,防止高频恶意刷屏。
二、第一步:集成PbootCMS内置图形验证码(基础防护)
PbootCMS自带图形验证码功能,无需额外引入第三方插件,可直接集成到各类表单中,作为第一道防护线,适配留言表单、联系表单等所有场景,操作分为「后台配置+前端渲染+后端验证」三步。
2.1 后台验证码配置(必做)
登录PbootCMS后台,完成验证码基础配置,确保验证码正常生成与验证:
进入后台【系统设置】→【配置参数】→【安全配置】,找到「验证码设置」区域;
开启验证码:将「是否开启验证码」设置为「是」,选择验证码使用场景(如「留言表单」「联系表单」,可多选);
配置验证码参数:设置验证码长度(推荐4位)、验证码字体大小、干扰线数量,建议保留默认配置(默认配置已能满足基础防护需求);
保存配置:点击页面底部【保存】,完成验证码基础配置,无需清除缓存即可生效;
验证GD库:若验证码无法显示,需检查服务器PHP环境是否开启GD库(可通过phpinfo()查看),开启方法:编辑php.ini文件,取消注释「extension=gd」或「extension=php_gd2.dll」,重启Web服务即可。
2.2 前端表单集成验证码(核心步骤)
找到需要添加验证码的表单模板(如留言表单:/template/当前模板目录/guestbook.html;联系表单:contact.html),在表单中添加验证码输入框与验证码图片,代码可直接复制复用,适配所有PbootCMS表单:
<!-- PbootCMS表单验证码集成(以留言表单为例) -->
<form action="{pboot:msgaction}" method="post" onsubmit="return checkForm()" class="guestbook-form">
<!-- 表单原有字段(姓名、电话、留言内容等) -->
<div class="form-item">
<label>姓名:</label>
<input type="text" name="contacts" placeholder="请输入您的姓名" required>
</div>
<div class="form-item">
<label>电话:</label>
<input type="tel" name="mobile" placeholder="请输入您的电话" required>
</div>
<div class="form-item">
<label>留言内容:</label>
<textarea name="content" placeholder="请输入留言内容" required></textarea>
</div>
<!-- 验证码模块(核心代码,可直接复制) -->
<div class="form-item captcha-item">
<label>验证码:</label>
<div class="captcha-box">
<input type="text" name="checkcode" placeholder="请输入验证码" required class="captcha-input">
<!-- PbootCMS内置验证码标签,点击可刷新 -->
<img src="{pboot:checkcode}" title="点击刷新验证码" onclick="this.src='{pboot:checkcode}?'+Math.round(Math.random()*10)" class="captcha-img">
</div>
</div>
<button type="submit" class="submit-btn">提交留言</button>
</form>
<!-- 验证码样式(可选,按需调整,贴合站点风格) -->
<style>
.form-item {
margin: 15px 0;
display: flex;
align-items: center;
gap: 10px;
}
.form-item label {
width: 80px;
text-align: right;
font-size: 14px;
color: #333;
}
.form-item input, .form-item textarea {
flex: 1;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.captcha-box {
display: flex;
align-items: center;
gap: 10px;
flex: 1;
}
.captcha-input {
width: 120px !important;
flex: none;
}
.captcha-img {
width: 100px;
height: 38px;
cursor: pointer;
border: 1px solid #ddd;
border-radius: 4px;
}
.submit-btn {
padding: 8px 24px;
border: none;
background: #007bff;
color: #fff;
border-radius: 4px;
cursor: pointer;
margin-left: 90px;
}
.submit-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
</style>2.3 前端验证码验证(避免无效提交)
在表单模板中添加JS代码,实现前端验证码非空验证、格式验证,减少无效请求,同时优化用户体验,代码如下(嵌入在表单下方):
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
// 表单提交验证(含验证码验证)
function checkForm() {
var checkcode = $("input[name='checkcode']").val().trim();
// 验证码非空验证
if (checkcode === "") {
alert("请输入验证码");
return false;
}
// 验证码格式验证(4位字符,与后台配置一致)
if (checkcode.length !== 4) {
alert("验证码格式错误,请输入4位字符");
return false;
}
// 可选:提交前禁用按钮,防止重复提交
$(".submit-btn").prop("disabled", true).text("提交中...");
return true;
}
// 验证码刷新优化(避免缓存导致刷新无效)
$(".captcha-img").click(function() {
$(this).attr("src", "{pboot:checkcode}?" + Math.random());
});
</script>2.4 后端验证码验证(关键,防止绕过前端)
前端验证可被绕过,必须在后端添加验证码验证逻辑,确保只有验证码正确的提交才能被处理。无需修改系统核心控制器,通过新增自定义验证文件实现,步骤如下:
进入服务器,找到PbootCMS根目录,进入
/apps/home/controller/目录,新建文件FormVerifyController.php;在该文件中编写后端验证码验证代码,复用PbootCMS内置验证逻辑,代码如下(完整可复用):
<?phpnamespace apphomecontroller;use apphomecontrollerBaseController;use thinkSession;// 表单验证控制器(验证码验证、反垃圾验证)class FormVerifyController extends BaseController{// 验证码验证方法(供表单提交时调用)public function checkCaptcha(){// 获取前端提交的验证码$checkcode = request('post.checkcode', '', 'trim');// 获取session中存储的验证码(PbootCMS内置,自动生成)$sessionCode = Session::get('checkcode');// 验证码验证逻辑if (empty($checkcode) || empty($sessionCode)) {return json(['code' => 0, 'msg' => '验证码不能为空']);}// 忽略大小写验证(提升用户体验,可选)if (strtolower($checkcode) !== strtolower($sessionCode)) {return json(['code' => 0, 'msg' => '验证码错误,请重新输入']);}// 验证通过,清除session中的验证码(防止重复使用)Session::delete('checkcode');return json(['code' => 1, 'msg' => '验证码验证通过']);}}?>修改表单提交逻辑,让表单先提交至验证码验证接口,验证通过后再提交至表单处理接口,修改前端表单的onsubmit事件和AJAX逻辑:
<script>// 替换原有checkForm函数,改为AJAX验证验证码function checkForm() {var checkcode = $("input[name='checkcode']").val().trim();var formData = $("form").serialize(); // 获取表单所有数据// 前端基础验证if (checkcode === "" || checkcode.length !== 4) {alert(checkcode === "" ? "请输入验证码" : "验证码格式错误");return false;}// AJAX提交至验证码验证接口$.ajax({url: "/index.php/home/formVerify/checkCaptcha", // 后端验证接口路径type: "POST",dataType: "json",data: {checkcode: checkcode},success: function(res) {if (res.code === 1) {// 验证码验证通过,提交表单至原处理接口$("form").off("submit").submit();} else {// 验证码错误,刷新验证码,提示用户alert(res.msg);$(".captcha-img").attr("src", "{pboot:checkcode}?" + Math.random());$("input[name='checkcode']").val("").focus();$(".submit-btn").prop("disabled", false).text("提交留言");}},error: function() {alert("验证码验证失败,请重试");$(".submit-btn").prop("disabled", false).text("提交留言");}});return false; // 阻止表单默认提交}</script>
三、第二步:添加多层反垃圾机制(核心防护)
仅靠验证码无法完全拦截恶意提交(如人工手动提交垃圾信息、高级机器人绕过验证码),需添加多层反垃圾机制,结合行为验证、内容过滤、高频限制,实现全方位防护。
3.1 行为验证(区分真人与机器人)
机器人提交表单通常瞬间完成,无正常填写行为,通过添加「表单填写时长限制」「提交按钮倒计时」,拦截异常提交,前端JS代码如下(嵌入在表单JS中):
<script>
// 行为验证:表单填写时长限制(至少填写3秒,防止瞬间提交)
var formStartTime = new Date().getTime(); // 记录表单加载时间
// 优化checkForm函数,添加时长验证
function checkForm() {
var formEndTime = new Date().getTime();
var fillTime = (formEndTime - formStartTime) / 1000; // 填写时长(秒)
// 填写时长不足3秒,拦截提交
if (fillTime < 3) {
alert("请认真填写表单内容");
return false;
}
// 原有验证码验证逻辑(省略,保持不变)
var checkcode = $("input[name='checkcode']").val().trim();
if (checkcode === "" || checkcode.length !== 4) {
alert(checkcode === "" ? "请输入验证码" : "验证码格式错误");
return false;
}
// 提交按钮倒计时(防止重复提交)
var btn = $(".submit-btn");
btn.prop("disabled", true).text("提交中...");
// AJAX验证码验证(省略,保持不变)
$.ajax({
url: "/index.php/home/formVerify/checkCaptcha",
type: "POST",
dataType: "json",
data: {checkcode: checkcode},
success: function(res) {
if (res.code === 1) {
$("form").off("submit").submit();
} else {
alert(res.msg);
$(".captcha-img").attr("src", "{pboot:checkcode}?" + Math.random());
$("input[name='checkcode']").val("").focus();
btn.prop("disabled", false).text("提交留言");
}
},
error: function() {
alert("验证码验证失败,请重试");
btn.prop("disabled", false).text("提交留言");
}
});
return false;
}
// 可选:添加鼠标移动检测(进一步区分真人与机器人)
var isHuman = false;
$(document).mousemove(function() {
isHuman = true; // 检测到鼠标移动,判定为真人
});
// 在AJAX请求前添加检测
$.ajax({
// 原有配置
beforeSend: function() {
if (!isHuman) {
alert("请通过真人验证");
return false;
}
}
});
</script>3.2 内容过滤(拦截垃圾信息)
在后端添加关键词过滤、空字段验证、隐藏字段陷阱,拦截包含垃圾关键词、恶意内容的提交,修改 FormVerifyController.php 文件,添加内容验证方法:
<?php
// 新增内容过滤方法(在FormVerifyController类中添加)
public function checkContent()
{
// 获取表单提交的所有数据
$formData = request()->post();
// 1. 空字段验证(防止只填验证码,其他字段为空的恶意提交)
$requiredFields = ['contacts', 'mobile', 'content']; // 需验证的必填字段
foreach ($requiredFields as $field) {
if (empty($formData[$field]) || trim($formData[$field]) === "") {
return json(['code' => 0, 'msg' => '请填写完整表单内容']);
}
}
// 2. 垃圾关键词过滤(可根据自身需求添加更多关键词)
$spamKeywords = ['广告', '推广', '刷单', '诈骗', '赌博', '色情', '网址', '链接', '微信', 'QQ'];
$content = $formData['content'] . $formData['contacts'] . $formData['mobile']; // 拼接所有字段,全面过滤
foreach ($spamKeywords as $keyword) {
if (strpos($content, $keyword) !== false) {
return json(['code' => 0, 'msg' => '提交内容包含违规信息,请重新填写']);
}
}
// 3. 隐藏字段陷阱(机器人会自动填充所有输入框,真人不会看到该字段)
if (!empty($formData['hidden_field'])) {
return json(['code' => 0, 'msg' => '恶意提交被拦截']);
}
// 内容验证通过
return json(['code' => 1, 'msg' => '内容验证通过']);
}
?>同时,在前端表单中添加隐藏字段(真人不可见,机器人会自动填充),并修改AJAX逻辑,添加内容验证步骤:
<!-- 在表单中添加隐藏字段(放在表单任意位置) --> <input type="hidden" name="hidden_field" value="" style="display: none;">
<script>
// 优化checkForm函数,添加内容验证步骤
function checkForm() {
var formEndTime = new Date().getTime();
var fillTime = (formEndTime - formStartTime) / 1000;
var checkcode = $("input[name='checkcode']").val().trim();
var formData = $("form").serialize();
// 1. 行为验证(填写时长)
if (fillTime < 3) {
alert("请认真填写表单内容");
return false;
}
// 2. 前端基础验证
if (checkcode === "" || checkcode.length !== 4) {
alert(checkcode === "" ? "请输入验证码" : "验证码格式错误");
return false;
}
// 3. 验证码验证
var btn = $(".submit-btn");
btn.prop("disabled", true).text("提交中...");
$.ajax({
url: "/index.php/home/formVerify/checkCaptcha",
type: "POST",
dataType: "json",
data: {checkcode: checkcode},
success: function(res) {
if (res.code === 1) {
// 4. 内容验证(新增步骤)
$.ajax({
url: "/index.php/home/formVerify/checkContent",
type: "POST",
dataType: "json",
data: formData,
success: function(contentRes) {
if (contentRes.code === 1) {
// 内容验证通过,提交表单
$("form").off("submit").submit();
} else {
alert(contentRes.msg);
btn.prop("disabled", false).text("提交留言");
}
},
error: function() {
alert("内容验证失败,请重试");
btn.prop("disabled", false).text("提交留言");
}
});
} else {
alert(res.msg);
$(".captcha-img").attr("src", "{pboot:checkcode}?" + Math.random());
$("input[name='checkcode']").val("").focus();
btn.prop("disabled", false).text("提交留言");
}
},
error: function() {
alert("验证码验证失败,请重试");
btn.prop("disabled", false).text("提交留言");
}
});
return false;
}
</script>3.3 高频限制(拦截高频恶意提交)
针对同一IP高频提交、单日多次提交的恶意行为,添加IP限制,通过PbootCMS内置缓存功能实现,修改 FormVerifyController.php 文件,添加IP限制方法:
<?php
// 新增IP高频限制方法(在FormVerifyController类中添加)
public function checkIpLimit()
{
$userIp = request()->ip(); // 获取当前用户IP
$cacheKey = 'form_submit_ip_' . $userIp; // 缓存键(以IP为标识)
$dayCacheKey = 'form_submit_ip_day_' . $userIp; // 单日限制缓存键
// 1. 高频提交限制(1分钟内最多提交1次)
$lastSubmitTime = cache($cacheKey);
if ($lastSubmitTime && (time() - $lastSubmitTime) < 60) {
return json(['code' => 0, 'msg' => '提交过于频繁,请1分钟后再试']);
}
// 2. 单日提交限制(同一IP单日最多提交5次)
$daySubmitCount = cache($dayCacheKey) ?: 0;
if ($daySubmitCount >= 5) {
return json(['code' => 0, 'msg' => '您今日提交次数已达上限,请明日再试']);
}
// 更新缓存:记录本次提交时间(1分钟有效期)
cache($cacheKey, time(), 60);
// 更新单日提交次数(24小时有效期)
cache($dayCacheKey, $daySubmitCount + 1, 86400);
// IP限制验证通过
return json(['code' => 1, 'msg' => 'IP验证通过']);
}
?>修改前端AJAX逻辑,添加IP限制验证步骤(放在内容验证之后、表单提交之前):
<script>
// 优化checkForm函数,添加IP限制验证
function checkForm() {
// 原有逻辑(行为验证、基础验证、验证码验证、内容验证,省略)
// ...
// 4. 内容验证
$.ajax({
url: "/index.php/home/formVerify/checkContent",
type: "POST",
dataType: "json",
data: formData,
success: function(contentRes) {
if (contentRes.code === 1) {
// 5. IP高频限制验证(新增步骤)
$.ajax({
url: "/index.php/home/formVerify/checkIpLimit",
type: "POST",
dataType: "json",
success: function(ipRes) {
if (ipRes.code === 1) {
// 所有验证通过,提交表单
$("form").off("submit").submit();
} else {
alert(ipRes.msg);
btn.prop("disabled", false).text("提交留言");
}
},
error: function() {
alert("系统验证失败,请重试");
btn.prop("disabled", false).text("提交留言");
}
});
} else {
alert(contentRes.msg);
btn.prop("disabled", false).text("提交留言");
}
},
error: function() {
alert("内容验证失败,请重试");
btn.prop("disabled", false).text("提交留言");
}
});
return false;
}
</script>四、第三步:表单提交异常处理与优化
为提升用户体验,需添加表单提交异常处理、验证失败反馈,同时优化验证码显示、表单样式,确保防护机制不影响正常用户提交。
4.1 提交结果反馈(用户体验优化)
修改表单处理逻辑,添加提交结果提示,避免用户重复提交,在表单模板中添加提示容器,修改JS代码:
<!-- 在表单下方添加结果提示容器 --> <div class="submit-result" style="margin-left: 90px; margin-top: 15px; font-size: 14px; display: none;"></div>
<script>
// 优化表单提交逻辑,添加结果提示
$("form").submit(function(e) {
e.preventDefault(); // 阻止默认提交,改用AJAX提交
var formData = $(this).serialize();
var btn = $(".submit-btn");
var resultBox = $(".submit-result");
$.ajax({
url: $(this).attr("action"), // 表单原处理接口(如{pboot:msgaction})
type: "POST",
dataType: "json",
data: formData,
success: function(res) {
if (res.code === 1) {
// 提交成功
resultBox.text("提交成功,感谢您的反馈!").css("color", "#28a745").show();
$(this)[0].reset(); // 重置表单
$(".captcha-img").attr("src", "{pboot:checkcode}?" + Math.random());
} else {
// 提交失败
resultBox.text("提交失败:" + res.msg).css("color", "#dc3545").show();
}
// 3秒后隐藏提示
setTimeout(function() {
resultBox.hide();
btn.prop("disabled", false).text("提交留言");
}, 3000);
},
error: function() {
resultBox.text("提交失败,请重试").css("color", "#dc3545").show();
setTimeout(function() {
resultBox.hide();
btn.prop("disabled", false).text("提交留言");
}, 3000);
}
});
});
</script>4.2 常见异常处理
验证码不显示:检查服务器GD库是否开启,清除后台缓存和浏览器缓存,确认验证码标签
{pboot:checkcode}正确调用,若仍不显示,可直接访问验证码接口(/index.php?p=/login/verify),查看是否返回错误信息;表单提交无反应:检查JS代码是否有语法错误,确认jQuery已正确引入,查看浏览器控制台报错信息,修复对应问题;
验证通过但表单提交失败:检查表单字段名称与后台配置一致,确认表单处理接口(如{pboot:msgaction})正确,查看服务器错误日志;
后台关闭验证码后仍提示验证码不能为空:若需临时关闭验证码,需修改
/apps/admin/controller/IndexController.php文件,找到验证码验证相关代码,修改为if (!$checkcode && $this->config('admin_check_code') && strtolower(post('checkcode', 'var')) != session('checkcode')) { json(0, '验证码不能为空!'); },避免关闭后仍提示异常。
五、功能测试与全面验证
5.1 测试流程(必做)
清除缓存:登录后台,点击【系统设置】→【清除缓存】,确保所有配置、代码生效;
正常提交测试:填写完整表单内容,输入正确验证码,确保提交成功,查看结果提示;
验证码验证测试:
不输入验证码,点击提交,确认提示“请输入验证码”;
输入错误验证码,确认提示“验证码错误”,且验证码自动刷新;
反垃圾机制测试:
瞬间提交表单(填写时长<3秒),确认拦截并提示;
提交包含垃圾关键词(如“广告”“刷单”)的内容,确认拦截;
手动填充隐藏字段,提交表单,确认拦截;
同一IP1分钟内多次提交,确认提示“提交过于频繁”;
同一IP单日提交超过5次,确认提示“提交次数达上限”;
异常提交测试:提交空表单、只填验证码,确认拦截并提示“请填写完整表单内容”。
5.2 测试注意事项
测试时需清除浏览器缓存,避免缓存导致验证逻辑失效;
IP限制测试需更换IP(或清除缓存),否则会被限制;
测试完成后,可根据站点实际需求,调整关键词列表、提交频率限制、单日提交次数;
建议开启服务器日志记录,便于后续追踪恶意提交行为,及时更新关键词库。
六、功能扩展(可选)
基于本文基础方案,可根据站点需求进行以下扩展,进一步提升反垃圾防护效果:
集成第三方行为验证码:替换内置图形验证码,使用极验、滑动验证码等第三方服务,拦截更高级的机器人,适配PbootCMS只需修改前端验证码渲染和后端验证接口;
关键词库优化:将垃圾关键词存储在数据库中,后台添加关键词管理功能,可实时添加、删除关键词,无需修改代码;
用户登录验证:若表单仅对登录用户开放,可添加用户登录验证,未登录用户无法提交,进一步减少恶意提交;
提交记录审计:后台添加表单提交记录管理,可查看所有提交记录,标记垃圾信息,批量删除,同时统计提交数据;
邮箱/手机验证:添加邮箱验证码、手机短信验证,仅验证通过的用户可提交表单,适合报名、注册等重要表单场景。
七、总结
本文通过「PbootCMS内置图形验证码+多层反垃圾机制」,实现了表单恶意提交的全方位防护,无需修改系统核心文件,代码可直接复用,适配各类表单场景,兼顾安全性与用户体验。核心优势在于:利用内置功能减少开发成本,多层防护层层递进,可有效拦截机器人提交、垃圾信息刷屏、高频恶意请求等问题,同时通过优化用户反馈,确保正常用户提交流畅。
开发过程中,需重点关注3点:一是后端验证不可少(前端验证可被绕过,后端验证是核心);二是防护机制需兼顾体验(避免过度防护导致正常用户无法提交);三是及时更新关键词库和防护规则(应对不断变化的恶意提交方式)。按照本文步骤操作,即可快速实现表单安全防护,保障站点稳定运营,减少人工审核成本。同时,建议开发前备份站点文件和数据库,避免操作失误导致数据丢失。
-
Pbootcms让一级栏目下的二级三级栏目高亮
2025-09-02
255 -
pbootcms编辑器过滤自定义的div代码解决办法
2025-08-20
63 -
pbootcms网站上线后如何做好防护才能不被黑或者被注入
2025-09-08
470 -
pbootcms上传缩略图截取尺寸缩小变模糊解决方案
2025-09-01
89 -
pbootcms模板后台登录页面在哪里修改
2025-09-01
158 -
PbootCMS通过layui上传实现留言文件上传功能
2025-09-02
79 -
如何将pbootcms系统搭建的手机网页封装成微信小程序并审核上架
2025-09-08
103 -
pbootcms模板文章列表序号怎么调用标签?
2025-08-29
74 -
PbootCMS网站转移后无法打开报错提示“No input file specifed”
2025-08-20
100 -
pbootcms上传缩略图限制尺寸图片模糊的修改方法
2025-08-20
77
咨询热线:
联系电话
联系邮箱
联系QQ
方案获取
