Портал для веб-мастера

Инструменты для Бизнеса

Вход пользователей
Поиск статей
WoWeb.ru » Статьи » Программирование для Web » PHP

Защита форм от спама
Практически любой проект имеет гостевую книгу, форум, формы отправки писем и другие интерактивные элементы. И практически все сталкиваются с поисковым спамом или подобными нарушениями. Наибольшие неприятности приносят скрипты-роботы, которые могут в считанные часы переполнить Вашу гостевую книгу рекламными сообщениями. Такой традиционный прием как блокировка IP адресов дает малый эффект, т.к. используются анонимные прокси серверы. Не менее популярный прием - это размещение графической картинки с изображением кода, который требуется ввести. Об этом эффективном приеме здесь и пойдет речь.

Среди встретившихся мне примеров реализации такой защиты, только в редких случаях она выносилась в отдельный модуль и еще реже оформлялась в виде классов, поэтому я написал свой.

При его разработке, учитывались следующие требования:
  • возможность многократного использования;
  • простота внедрения;
  • отвязка от использования MySQL и текстовых файлов;
  • отказ от прямого вывода изображения в поток (это делается в подавляющем большинстве случаев, но у меня часто используется формирование текста страницы в буфере-строке);
  • гибкие настройки работы модуля (размер, шрифт, виды защиты и т.п.).
В результате получился класс, немного упрощенный код которого приведен ниже. Вы можете без проблем использовать его у себя, подстроив под свои задачи и нужды. Также он очень легко интегрируется в любой интерфейс. Рассмотрим подробно его код.

Модуль tuning.php
 <?php //Каталог куда будет выкладывать сгенерированная картинка define('CACHE_DIR_OUT', '../public_html/cache/'); //Каталог из которого будет браться url картинки define('CACHE_DIR_URL', '/cache/'); define('HASH_DELTA', 3914); //случайное смещение кода define('HASH_FIELDNAME', 'hh'); //название поля с хешем class TProtectCode{ var $width = 85; //Высота картинки var $height = 40; //Ширина картинки var $transparent = 1; //Прозрачность var $interlace = false; var $msg = 'TUNING'; //Отображаемый текст //Настройка шрифта var $fonttype = ''; //Вид шрифта, если не задан, то используется системный var $font = 5; // full path to your font var $tuningfount; var $size = 14; var $rotation = 0; //Отступ текста от края var $pad_x = 0; var $pad_y = 0; // RGB цвет текста var $fg_r = 0; var $fg_g = 0; var $fg_b = 0; // RGB цвет фона var $bg_r = 255; var $bg_g = 255; var $bg_b = 255; //Признаки вывода помех var $ShowDot = true; var $ShowFig = false; //Для хеша var $hashcode; //сам код var $hashvalue; //его зашифрованное значение var $hashfield; //текст поля, для удобства при частом использовании function TProtectCode(){ //эту проверку можно убрать, если будут использоваться только системные шрифты if (!function_exists('imagettftext')){ die('Your server does not have FreeType installed in php.'. ' True Type Fonts (.ttf) are not supported'); } $this->tuningfount = $this->font; } //генерируем код, на вход подается диапазон, в котором будет выбираться случайное число и //имя поля формы с кодом, для которой строится html код function GetCode($hmin=1000, $hmax=9999, $fieldname=HASH_FIELDNAME){ //сам код $this->hashcode = rand($hmin, $hmax); //получаем хеш трансформированного числа $this->hashvalue = md5($this->hashcode + HASH_DELTA); $this->hashfield = ''; } //проверяем корректность полученного кода и его хеша function CheckCode($code, $hash){ return ($hash == md5($code + HASH_DELTA)); } function DrawImage() { $image = ImageCreate($this->width+($this->pad_x*2),$this->height+($this->pad_y*2)); // Цвет фона $bg = ImageColorAllocate($image, $this->bg_r, $this->bg_g, $this->bg_b); // Цвет текста $fg = ImageColorAllocate($image, $this->fg_r, $this->fg_g, $this->fg_b); if ($this->transparent) ImageColorTransparent($image, $bg); ImageInterlace($image, $this->interlace); if ($this->fonttype == 'ttf'){ //для TrueType шрифтов ImageTTFText($image, $this->size, $this->rotation, $this->pad_x, $this->pad_y, $fg, $this->font, $this->msg); } else { //Системный шрифт ImageString($image, $this->tuningfount, $this->pad_x, $this->pad_y, $this->msg, $fg); } //Вносим в изображение шум if ($this->ShowFig){ $dc = ImageColorAllocate($image, rand(0,255), rand(0,255), rand(0,255)); ImageRectangle($image, rand(0, $this->width/2 ), rand(0, $this->height/2 ), rand($this->width / 2, $this->width) ,rand($this->height / 2, $this->height), $dc); $dc = ImageColorAllocate($image, rand(0,255), rand(0,255), rand(0,255)); ImageRectangle($image, rand(0, $this->width/2 ), rand(0, $this->height/2 ), rand($this->width / 2, $this->width) ,rand($this->height / 2, $this->height), $dc); } //Шумы в виде точек if ($this->ShowDot){ for($i = $this->width * $this->height / 10; $i >= 0;$i--) { ImageSetPixel($image, rand(0,$this->width), rand(0,$this->height), ImageColorAllocate($image, rand(0,255), rand(0,255), rand(0,255))); } } //файл в который производится вывод картинки, для вывода сразу на экран //можно использовать вызов ImagePNG($image) $fname = 't.png'; ImagePNG($image, CACHE_DIR_OUT.$fname); ImageDestroy($image); //url картинки return CACHE_DIR_URL.$fname; } } ?> 
Описанный класс очень прост в использовании и может применять многократно в проекте, с помощью всего лишь нескольких вызвовов. Рассмотрим примеры использования модуля tuning.php (фрагменты кода). Для получения самого кода и url картинки может использоваться код такого типа:
 require_once('tuning.php'); $t = new TProtectCode; $t->width = 35; $t->height = 15; $t->GetCode(); $t->msg = $t->hashcode; $tuning_url = $t->DrawImage(); $tuning = 0; 
Вывод картинку с защитным кодом в некоторой форме, можно организовать так:
 <form> <table> <tr> <td>*Код:</td> <td align=left> <img src='{$tuning_url}' border=0 width=35 height=15></a>  <input style="width: 100px;" type=text name=tuning maxlength=4 value="{$tuning}">{$t->hashfield} </td> </tr> <table> </form> 
Для проверки корректности кода удобно использовать отдельную функцию:
 function checktuning($tuning, $hash){ require_once('tuning.php'); $t = &new TProtectCode; if (!$t->CheckCode($tuning, $hash)){ echo "Неправильно введен защитный код !"; return false; } return true; } 
Чтобы считать переданные из формы значения кода и хеша:
 $this->tuning = isset($_POST['tuning']) ? intval($_POST['tuning']) : 0; $this->page = isset($_GET['page']) ? intval($_GET['page']) : 1; 
Итак, как Вы видите все довольно просто. Пример его использования Вы можете увидеть в моей гостевой книге. Сейчас готовится его применение для защиты от накруток в САР (здесь нужна небольшая модификация кода), также он уже используется в других моих проектах. Буквально с первого дня он отсек потом спама, который уже начал доходить до 10-12 сообщений в день.

Преимущества такого подхода очевидны:
  • нет никакой необходимости в БД и файлах, для хранения кода - это значительно снижает требования по ресурсам;
  • Вы можете сами менять алгоритм защиты, например, взять не одну функцию md5, а сочетание md5 и crypto, что сделает передаваемый код практически неуязвимым для взлома;
  • возможность сохранения картинки в файле, расширяет область применения такой защиты;
  • очень гибкие настройки позволят Вам, везде применять этот класс.
Приведенный скрипт естественно можно и нужно дорабатывать и улучшать. В этом примере я специально убрал специфичные для своего проекта фрагменты кода, чтобы показать универсальный пример, который в то же время готов к реальному использованию.

Надеюсь приведенный пример поможет Вам в работе и буду рад Вашим отзывам!


Статья предоставлена автором для WoWeb.ru

Автор: Брудасов Сергей · Добавлена: 2005-12-11
Просмотров: 7038 · Рейтинг: 3.6

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Категории раздела
Flash
Apache
WWW
PhotoShop
Веб-дизайн
Раскрутка и реклама
Базы данных
3D графика
Хостинг
Истории веб-мастеров
Web-технологии
Сетевая безопасность
Программирование для Web
Операционные системы

Новые статьи
Лучшие статьи
Популярные статьи
Комментируемые статьи
Разделы сайта
Скрипты
Статьи
Шрифты
Флэш исходники
HTML шаблоны
Партнерки
Клипарты
Смайлы
Фоны
Гифы
Иконки
Опрос сайта
Ведете ли вы блог?
Всего ответов: 60296
Наша кнопка
WoWeb.ru - портал для веб-мастера