as_snipercaptcha: CSS/DHTML (без GD-библиотек) CAPTCHA класс

as_snipercaptcha.php содержит PHP класс (CSniperCaptcha) для распространенной задачи, известной под абревиатурой CAPTCHA - защиты интерактивных сайтов и форм от спам-роботов.
В отличие от большинства аналогичных CAPTCHA - движков, здесь не используются графические библиотеки генерации изображений (типа GD) и не создается картинок с искаженными буквами и цифрами для распознавания человеком (подобных классов в Сети достаточно).
Основная идея проста : пользователь (посетитель сайта) не вводит увиденные буквы/цифры в специально отведенное INPUT - поле, вместо этого он видит на экране таблицу (сетку) из нескольких строк и столбцов, где одна из ячеек "подсвечена" специальной картинкой-указателем. Он щелкает по этой ячейке мышью, в ответ указатель переходит на другую ячейку. Т.е. "кодовое слово" в нашем случае состоит из верной последовательности выбранных ячеек. В ответ на каждое нажатие (клик) мыши браузер отправляет ответ (ID ячейки) на сервер с помощью AJAX-запроса, дожидается ответа, в котором содержатся координаты следующей цели, в которую надо "попасть". Когда вся последовательность выполнена, с сервера приходит ответ о том, пройден или нет тест на "человечность" пользователя. При желании Вы можете соответствующим Javascript-кодом обработать ответ и выполнить определенные действия на форме клиента.

Установка as_snipercaptcha

  1. Скачав дистрибутивный zip-файл, распакуйте его в любую папку. В заголовках скриптов, которые будут использовать наш класс, не забудьте вписать
    require_once('as_snipercaptcha.php');
    Указывать ли путь к файлу, как всегда зависит от того, куда Вы скопируете модуль.
    Если на Вашем сайте уже используется фреймворк jQuery, рекомендуется использовать jquery-версию класса - as_snipercaptcha_j.php. Необходимость в файле as_jsfunclib.js в этом случае отпадает. К тому же jQuery-версия класса может обладать лучшей совместимостью с разными браузерами.
  2. Перенесите/скопируйте файлы изображений (*.png, *.gif) в Вашу основную папку "images" на сайте, и "путь" к папке задайте в константе IMGPATH (либо просто положите файлы в один каталог с Вашим скриптом) :
    define('IMGPATH','allimages/');
    Файл captchasight.png - это "маркер", которым помечается очередная ячейка выбора. cap_progress.png нужен для отрисовки столбика "термометра", показывающего прогресс процедуры проверки.
  3. Для формирования AJAX-запросов нам понадобится библиотека функций as_jsfunclib.js. Поэтому скопируйте/перенесите этот файл в свою папку с js-скриптами либо в текущую папку. Если файл будет в другой папке, не забудьте указать путь в методе DrawRefs() (см.ниже)
  4. Стили, используемые при отрисовке решетки, вынесены в отдельный файл as_captchastyles.css - оставьте его в рабочей папке или перенесите в свою папку для стилей - в этом случае укажите путь к ней при вызове метода DrawRefs() (см.ниже).

Использование класса CSniperCaptcha

CSniperCaptcha генерирует небольшую HTML таблицу (или "решетку"), которая может содержать переменное число строк,столбцов, а также переменную ширину-высоту одной ячейки. Эти размерности могут быть жестко заданы Вами при вызове конструктора класса. Если их не задать, эти значения будут выбраны случайным образом из диапазонов 3...6 строк и 4...10 колонок.
Случайный выбор призван затруднить обход CAPTCHA-защиты возможным спам-роботом или другим модулем "распознавания". Вот как все работает :
  1. Когда сетка для CAPTCHA движка готова и выведена браузером на экран, вычисляются ее координаты и посылаются на сервер с помощью AJAX-вызова.
  2. Получив эти координаты, сервер начинает последовательность проверки: он поочередно выбирает (случайным образом) следующую ячейку, которая должна быть "кликнута" пользователем, и посылает ее вычисленные координаты в ответе клиенту. Координаты вычисляются исходя из переданного положения решетки, ее размерности и ширины-высоты одной ячейки.
  3. Клиент, получив координаты очередной ячейки, передвигает DOM-элемент "Image" в указанное место и ожидает щелчка мышью.
  4. Посетитель сайта щелкает по указанной ячейке, ее id отправляется на сервер.
  5. Когда все NN шагов выбора сделаны, и сервер получает последний ответ, он проверяет корректность ответов и запоминает результат в наборе сессионных переменных, а также отправляет клиенту в последнем ответе.
Если Вы подготовите свои Javascript-функции для обоих случаев (CAPTCHA-тест пройден, провален), их имена можно передать в класс, и тогда они будут выполнены соответственно при успешном или "проваленном" тесте. Например, можно показать изначально скрытые поля ввода текста, или разблокировать кнопки и др.элементы ввода. Функции будут вызваны сразу по получении ответа от сервера на последний выбор ячейки "проверочной" решетки.

Приведем простейший пример работы с классом. (Решетка для CAPTCHA-теста будет сгенерирована со случайным числом строк и столбцов, и размером ячейки).

require_once('as_snipercaptcha.php');

$captcha = new CSniperCaptcha();
// вывести основной HTML код, включая начальные теги формы - <FORM ...> и необходимые поля ввода

CSniperCaptcha::DrawRefs(); // вывожу ссылки на используемые CSS и js файлы
$captcha->Draw(); // отображается опросная решетка

//... теперь вывести кнопку SUBMIT и закрывающие теги формы </FORM>

$captcha->DrawJsCode(); // выводятся сопутствующие javascript-функции

// остальной HTML код ...

CSniperCaptcha - список методов

  • CSniperCaptcha($codelen=4, $submitid='', $jscode_success='',$jscode_fail='', $reinit=false) - конструктор класса.


  • Параметры:
  • SetServerScript($uri) - этот метод задает имя (URI) серверного скрипта, выполняющего проверку CAPTCHA теста. По умолчанию весь обмен во время проверки ведется с тем же скриптом, который вывел форму.


  • Параметры:
  • DrawRefs($csspath='',$jspath='') - метод формирует и выводит <STYLE> и <SCRIPT> теги со ссылками на файлы captcha_styles.css и as_jsfunclib.js, используемые в классе (входят в дистрибутив). Если Вы перенесете все стили из прилагаемого файла captcha_styles.css в централизованный набор, используемый на всем сайте, и потому не хотите выводить ссылку на css, передайте false в параметр $csspath. Аналогично - для $jspath.

    Параметры:
  • SetBufferedOutput($buffered=true) - задает режим "буферизованного" вывода, при котором весь сгенерированный HTML код не идет в поток клиенту. Вместо этого все методы (Draw(), DrawJsCode(), DrawRefs()) возвращают соответствующий HTML код.
    Это необходимо, когда разработчик сначала собирает всю HTML страницу в памяти, и только потом выводит ее в поток клиенту.

    Параметр $buffered - необязательное значение режима вывода, (логическое true|false или целое). По умолчанию true. False (или 0) задает режим "небуферизованного вывода".
  • Draw($width=0, $height=0, $cellsize=0, $tovar=0) - метод формирует (и выводит) HTML код CAPTCHA-решетки.


  • Параметры:
  • DrawJsCode($autostart=1) - этот метод выводит Javascript-скрипты необходимые для работы класса. Вызывать это метод нужно после вывода формы с кодом CAPTCHA (т.е. после вывода кода, сгенерированного методом Draw()). Исключение составляет случай "отложенного" старта процедуры проверки (см. параметры)

    Параметры:

    Полный пример использования

    Мы будем выводить решетку CAPTCHA со случайными размерами. Длина кодового слова - 5 (пользователь должен будет последовательно выбрать 5 ячеек из решетки). Когда проверка закончится, кнопка отправки SUBMIT должна бвть автоматически разблокирована.
    (Заметьте, что мы выводим ее с начальным тегом DISABLED).
    require_once('as_snipercaptcha.php');
    
    $captcha = new CSniperCaptcha(5, 'btn_submit'); // here SESSION is started, so NO HTML output before this !
    
    // т.к. этот же скрипт принимает данные по нажатию SUBMIT, здесь же включаем блок обработки формы:
    if(!empty($_POST)) {
      if($captcha->CheckPassed()){
         // process user data (publish to the database etc.
         PublishNewMessage(); // Your function that does a job
         echo "Спасибо, Ваше сообщение добавлено !";
      }
      else {
         echo "Вы робот, до свидания";
      }
      exit;
    }
    
    CSniperCaptcha::DrawRefs(); // вывожу ссылки на CSS и js файлы
    // выводим HTML код, стартующий FORM тег
    // и все поля ввода (TEXTAREA и др.) без кнопки 'submit'
    echo "Отправка сообщения";
    $self = $_SERVER['PHP_SELF'];
    
    CSniperCaptcha::DrawRefs('my_css/','my_js/'); // вывожу ссылки на используемые CSS и js файлы
    
    echo "<FORM action='$self' method='POST' name='myform'>";
    echo "<TEXTAREA name='messagetext' style='width:100%; height:120px'></TEXTAREA><br />";
    
    $captcha->Draw();
    
    echo "<input type='SUBMIT' id='btn_submit' name='btn_submit' value='Submit message' DISABLED />
    echo "</FORM>";
    $captcha->DrawJsCode();
    //... вывод остального HTML кода
    
    
    Вы можете использовать AJAX (XmlHTTPRequest) для получения от клиента данных с формы (данные отправляются, и выводится результат без полной перерисовки всего экрана), Ваш серверный backend php скрипт до обработки данных должен проверить, прошел ли пользователь тест CAPTCHA :
    // backend for processinbg posted data
    require_once('as_snipercaptcha.php');
    $captcha = new CSniperCaptcha();
    if($captcha->CheckPassed()) {
       PublushFormData($_POST); // здесь данные заносятся в базу и т.д.
       echo "Спасибо, сообщение сохранено"; // ajax response will go to the client
    }
    else echo "Ошибка, тест CAPTCHA не пройден";
    
    

    История (версии)

    1.03.007 (10.12.2008)
    1.03.006 (03.12.2008)
    1.02.004 (10.05.2008)
    1.0.001 (28.02.2008)


    Copyright © Alexander Selifonov, as-works.narod.ru