mekras / botobor
PHP反垃圾邮件库
Requires
- php: >=5.0.0
This package is auto-updated.
Last update: 2024-08-29 04:11:41 UTC
README
工作原理
目前最常见的保护网页表单不受机器人攻击的方法是,要求用户证明他们是人类,通过执行机器人难以完成的行为(CAPTCHA)。然而,从用户使用的角度来看,这并不太理想。因为这样会强制用户执行他们不需要且可能复杂的操作。
Ned Batchelder 提出了一个不同的思路。与其让用户感到烦恼,不如让机器人暴露自己。关于这一点,他详细介绍了他的文章 通过散列和诱饵停止垃圾邮件机器人。
Botobor 是一个 PHP 库,实现了 Ned 的想法。目前使用了以下几种检查(任何一种都可以禁用)
- 表单创建与发送之间的时间太短;
- 表单创建与发送之间的时间太长;
- 至少填写了一个诱饵字段(见下文);
- REFERER 头部与表单放置的地址不匹配。
有人可能会说:“哎呀,这太简单了!”。当然,确实如此。但 Botobor 并不追求绝对的保护(这种保护是难以实现的)。Botobor 的目标更实际——减少机器人填写表单的可能性,同时不增加用户的工作量。顺便说一下,Botobor 和 CAPTCHA 可以同时使用:Botobor 作为第一道防线,CAPTCHA 作为第二道防线,以防用户的人类身份有疑问。关于这一点将在下面详细说明。
安装
首先,您可以简单地下载文件 botobor.php
,并以您喜欢的任何方式将其连接到您的项目。
其次,可以使用 composer
php composer.phar require mekras/botobor:~0.4.0
使用
简单示例
创建表单的 PHP 代码
<?php require 'path/to/botobor.php'; ... // Получите разметку формы тем способом, который предусмотрен у вас в проекте, например: $html = $form->getHTML(); // Создайте объект-обёртку: $bform = new Botobor_Form($html); // Получите новую разметку формы $html = $bform->getCode();
处理表单的 PHP 代码
<?php require 'path/to/botobor.php'; ... if (Botobor_Keeper::get()->isRobot()) { // Форма отправлена роботом, выводим сообщение об ошибке. }
带选项的示例
您可以使用选项来更改 Botobor 的行为。例如,对于评论表单,合理的做法是增加 lifetime
参数(表单创建和发送之间的最大时间间隔),因为访客在评论之前可能需要长时间阅读文章。
可以这样操作
<?php $bform = new Botobor_Form($html); $bform->setLifetime(60); // 60 минут
有关选项的更多信息,请参阅 API 文档 中 setCheck
、setDelay
和 setLifetime
方法的描述。
带诱饵的示例
诱饵字段旨在捕捉那些能够自行找到表单的机器人蜘蛛。这类机器人通常会在表单中寻找熟悉字段(例如 name)并填写它们。Botobor 可以在表单中添加对人类不可见的(通过 CSS 隐藏)字段,并使用这些名称。人类将留下这些字段空白(因为他们看不到),而机器人则会填写它们,从而暴露自己。
在这个例子中,“name” 字段将被设置为诱饵。此时,真正的“name”字段的名称将被替换为随机值。在调用 Botobor_Keeper::handleRequest
方法(在 Botobor_Keeper::isRobot
中自动调用)时将进行反向转换。
$bform = new Botobor_Form($html); $bform->setHoneypot('name');
定义失败的检查
有时可能需要知道 Botobor 为什么认为访客是机器人,访客没有通过哪项检查。为此,可以使用 Botobor_Keeper::getFailedCheck()
方法,它返回失败检查的名称。检查的名称在 API 文档中指定。
与CAPTCHA的联合使用
BotBlocker可以与CAPTCHA联合使用。一个可能的方案如下。如果BotBlocker检测到表单是由机器人填写的,可以像Yandex在类似情况下所做的那样,要求输入图片中的验证码。在代码中,这可能表现为以下形式
<?php function checkRequest() { // Проверяем, использовался ли CAPTCHA в этом запросе if ($someCaptcha->isUsedInThisRequest()) { /* * Попадание сюда говорит о том, что посетитель уже проходил, но не прошёл проверку * Ботобором и сейчас проходит проверку CAPTCHA. По итогам этой проверки мы либо признаём в * посетителе человека, либо окончательно отказываем ему. */ if (!$someCaptcha->isPassed()) { $this->showErrorNotify(); } } elseif (Botobor_Keeper::get()->isRobot()) { /* * Попадание сюда горовит о том, что посетитель не прошёл проверку Ботобором. На случай если * это было ложное срабатывание, мы дадим посетителю возможность пройти CAPTCHA, чтобы * доказать, что он не робот. */ $this->showCaptcha(); } // Посетитель — человек, можно обрабатывать его запрос $this->processRequest(); }