
本文介绍在共享主机环境下,通过 csrf 防护、响应缓存、ip 限流与无感验证码(如 recaptcha v3)的组合策略,低成本、低侵入性地拦截恶意爬虫搜索,避免触发 sql 执行限额,同时不损害真实用户的搜索体验。
本文介绍在共享主机环境下,通过 csrf 防护、响应缓存、ip 限流与无感验证码(如 recaptcha v3)的组合策略,低成本、低侵入性地拦截恶意爬虫搜索,避免触发 sql 执行限额,同时不损害真实用户的搜索体验。
在构建面向公众的基础搜索功能时,尤其是部署于资源受限的共享主机环境,数据库查询频次上限往往成为瓶颈。单纯依赖 CSRF Token(如从首页表单携带 token 提交 GET 搜索)虽能阻断跨站伪造请求,但对主动构造 HTTP 请求的自动化脚本(如 Python + requests 的批量爬虫)完全无效。因此,需采用分层防御(Defense-in-Depth)思路,在不增加用户操作负担的前提下,显著提升机器人调用成本。
✅ 1. 基础防护:CSRF Token(已实施,需确保正确使用)
确保每个搜索入口(如首页 <form></form>)动态生成并校验一次性 token,且 token 绑定用户会话($_SESSION['csrf_token'])。注意:GET 请求中传递 token 须通过隐藏字段或 URL 参数(如 ?q=term&_token=abc123),后端必须验证其有效性与时效性(建议有效期 ≤ 30 分钟)。示例校验逻辑(PHP):
if (!hash_equals($_SESSION['csrf_token'] ?? '', $_GET['_token'] ?? '')) {
http_response_code(403);
die('Invalid or expired token');
}⚠️ 注意:CSRF 仅防“非预期提交”,不防“有意模拟用户行为”的爬虫——后者可先 GET 首页获取 token,再发起搜索。
✅ 2. 性能与防护双赢:高频搜索结果缓存
多数搜索具有强重复性(如“iPhone 15”“天气 北京”)。对查询参数做标准化处理(小写、去空格、过滤控制字符),生成缓存键(如 sha256("q=iPhone+15&lang=zh")),将结果(含 HTTP 状态码、响应体、TTL)存入 Redis 或 APCu。命中缓存则直接返回,跳过数据库查询:
$cacheKey = 'search_' . hash('sha256', strtolower(trim($_GET['q'])) . '_' . ($_GET['lang'] ?? 'zh'));
if ($cached = $redis->get($cacheKey)) {
echo $cached;
exit;
}
// ... 执行 SQL 查询 ...
$redis->setex($cacheKey, 300, $response); // 缓存 5 分钟✅ 3. 行为节制:基于 IP 的请求速率限制
对 /search.php 路由启用轻量级限流(如每分钟最多 10 次请求)。使用内存存储(如 Redis)记录 IP 的请求时间戳列表,超限时返回 HTTP 429 Too Many Requests 或静默延迟(如 sleep(1)),避免激怒真实用户。关键代码逻辑:
$ip = $_SERVER['REMOTE_ADDR'];
$window = 60; // 秒
$maxReq = 10;
$key = "rate:search:{$ip}";
$count = $redis->incr($key);
if ($count == 1) $redis->expire($key, $window);
if ($count > $maxReq) {
http_response_code(429);
header('Retry-After: 60');
die('Too many requests. Please try again later.');
}✅ 4. 无感识别:集成 reCAPTCHA v3
无需用户点击验证框,reCAPTCHA v3 在后台分析用户行为(鼠标轨迹、页面停留、JS 执行环境等),返回 0.0–1.0 的分数(1.0 表示极可能是真人)。在搜索表单中注入客户端脚本,并在提交前校验 token:
<!-- 页面底部 -->
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
<script>
grecaptcha.ready(() => {
grecaptcha.execute('YOUR_SITE_KEY', {action: 'search'}).then(token => {
document.getElementById('search-form').appendChild(
Object.assign(document.createElement('input'), {
type: 'hidden', name: 'g-recaptcha-response', value: token
})
);
});
});
</script>后端校验(需服务端调用 Google API):
$recaptcha = file_get_contents(
'https://www.google.com/recaptcha/api/siteverify?secret=' .
YOUR_SECRET_KEY . '&response=' . $_POST['g-recaptcha-response']
);
$result = json_decode($recaptcha, true);
if (!$result['success'] || $result['score'] < 0.5) {
http_response_code(403);
die('Automated request blocked.');
}? 总结建议:
- 优先启用缓存与 IP 限流(开发成本最低,见效最快);
- reCAPTCHA v3 是当前平衡安全性与体验的最佳实践,务必设置合理的
action和阈值(默认 0.5 可根据业务调整); - 避免全量日志记录所有搜索,但应审计低分请求(
score )与高频 IP,用于动态调优策略; - 定期清理过期缓存与限流计数器,防止内存泄漏。
这套组合方案不强制用户交互,却能在共享主机约束下,将无效自动化搜索降低 80% 以上,真正实现“安全不妥协体验”。


















