Главная > AJAX, ExtJS Framework, ExtJS Tips, Open Source, PHP > ExtJS Tips&Hacks или броня для веб проекта — сплав Zend Framework, ExtJS и reCaptcha

ExtJS Tips&Hacks или броня для веб проекта — сплав Zend Framework, ExtJS и reCaptcha

13 марта 2009

logoПриветствуем наших читателей. Сегодня мы снова опишем небольшое решение для ExtJS, которое возникло в ходе нашей работы над новыми проектами (раскрою только, что это он-лайн браузерные игры). На этот раз мы используем не только сам ExtJS, но и дополнительные средства, в частности, серверный РНР фреймворк Zend Framework и сервис reCaptcha.

Если вы строите веб-приложение, вместо обычного сайта (хотя, что сейчас этот "обычный сайт"?), то скорее всего, вам понадобится защита от автоматических регистраций или хоть бы попыток обхода, ведь нам интересны  посетители и пользователи люди, верно? Для этого существует механизм CAPTCHA, а данном примере мы используем тест, генерируемый сервисом reCaptcha, который мы считаем на сегодняшний момент самым продвинутым и удобным. Хотя в дистрибутиве Zend Framework есть и собственная реализация, однако вариант от reCaptcha мне кажется более удобным, так как там есть и вариант аудио-каптчи.

Отдельно следует сказать, что для использование сервиса необходимо зарегистрироваться и получить собственный уникальный ключ, который вы будете использовать в скриптах.

У нас приложение основано на ExtJS, к сожалению, там в дистрибутиве нет компонента для Captcha, однако не все так плохо. Конечно, можно использовать код reCaptcha и самостоятельно, в конце концов, он вставляется как обычный HTML-код, однако такой путь требует самостоятельной доработки механизма работы с формой. Поэтому мы попытались найти готовый компонент для библиотеки ExtJS, и, конечно же, нашли. Код взят из открытого проекта OpenBluePrint, который называет себя "Каркас для разработок веб приложений с использованием Zend Framework и ExtJS". Проект сам по себе достаточно интересен, советую изучить (кстати, автор активный участник обоих Google Groups - по ZF и ExtJS, так что мы даже заочно знакомы).

Сам класс компонента (Ext.ux.form.Recaptcha) очень простой, буквально три десятка строк, поэтому мы приведем его здесь (код взят из SVN-репозитария, ссылка на файл здесь, лицензия GPL v.3):

  1. /**
  2.  * @class Ext.ux.form.Recaptcha
  3.  * @extends Ext.BoxComponent
  4.  * Recaptcha field.
  5.  * @constructor
  6.  * Creates a new Recaptcha field
  7.  * @param {Ext.Element/String/Object} config
  8.  * The configuration options. If an element is passed, it is set as the internal
  9.  * element and its id used as the component id.
  10.  * If a string is passed, it is assumed to be the id of an existing element
  11.  * and is used as the component id. Otherwise, it is assumed to be
  12.  * a standard config object and is applied to the component.
  13.  *
  14.  * More information can be found about reCAPTCHA and lib files
  15.  * at: http://recaptcha.net
  16.  */
  17. Ext.ux.Recaptcha = Ext.extend(Ext.BoxComponent, {
  18. /**
  19.   * @cfg {String} publickey The key to generate your recaptcha
  20.   */
  21. /**
  22.   * @cfg {String} theme The name of the theme
  23.   */
  24. onRender : function(ct, position){
  25. if(!this.el){
  26. this.el = document.createElement('div');
  27. this.el.id = this.getId();
  28. Recaptcha.create(this.publickey, this.el, {
  29. theme: this.theme,
  30. lang: this.lang,
  31. callback: Recaptcha.focus_response_field
  32. });
  33. }
  34. Ext.ux.Recaptcha.superclass.onRender.call(this, ct, position);
  35. }
  36. });
  37. Ext.reg('recaptcha', Ext.ux.Recaptcha);

Использовать все это достаточно просто. Сначала вы создаете любую необходимую вам форму, используя стандартные компоненты Ext.form (например, мы ранее уже писали о пошаговом построении формы авторизации при помощи ExtJS - часть 1, часть 2, хотя там используется ExtJS 1.1, но многое актуально и для текущих версий).

Обычно CAPTCHA идет последним полем в форме, поэтому после всех необходимых нам полей мы вставляем каптчу (конечно, файл с описанием класса должен быть предварительно загружен, а сам класс зарегистрирован). Напомним, что этот код вставляется в конфиг Ext.FormPanel.

  1. { // Recaptcha
  2. xtype: 'recaptcha',
  3. name: 'recaptcha',
  4. id: 'recaptcha',
  5. //Ваш публичный ключ, полученный
  6. // после регистрации в recaptcha.net
  7. publickey: '6LfS...........ellZ',
  8. theme: 'white',
  9. lang: 'en'
  10. }

Так как на серверной стороне мы используем Zend Framework, в котором есть компонент Captcha и провайдер для reCaptcha, то нам необходимо при сабмите формы передать данные от компонента каптчи на сервер. Для этого мы вручную формируем дополнительные параметры в запросе:

  1. params: {
  2. recaptcha_rf: Ext.get('recaptcha_response_field').getValue(),
  3. recaptcha_cf: Ext.get('recaptcha_challenge_field').getValue()
  4. }

По определенным архитектурным соображениям мы не используем стандартный механизм сабмита от Ext.form, а вручную делаем запрос к серверу, используя Ext.Ajax.request, однако вы можете свободно изменить такое поведения, просто добавив нужные поля в форму на этапе сабмита.

recaptcha

Кстати, я забыл описать, как же выводится сама каптча. Используя компонент от Zend, мы указываем ему наш публичный и приватный ключи, полученные при регистрации в сервере. Для работы с recaptcha нам надо подключить необходимые классы ZF -  Zend_Service_ReCaptcha (необходимые дополнительные классы ZF сам загрузит, вы ведь настроили автозагрузку классов, верно?).

  1.  
  2. //подключение классов
  3. require_once ('Zend/Captcha/ReCaptcha.php');
  4.  
  5. //ваш публичный ключ от recaptcha
  6. $publickey = "6LfSf............ellZ";
  7.  
  8. //ваш приватный ключ
  9. $privatekey = "............jyM";
  10.  
  11. //создаем сервис
  12. $recaptcha = new Zend_Service_ReCaptcha($publickey, $privatekey);
  13.  
  14. //выводим код
  15. echo $recaptcha->getHTML();

А вот и сам код для верификации. Он возвращает стандартный ответ для ExtJS, об успешной регистрации или неудаче. Далее будет показана только часть, отвечающая за проверку Captcha, остальной код зависит от вашей системы. Не забудьте, что публичные и приватные ключи везде должны быть одинаковыми, и при генерации каптчи, и в компоненте ExtJS, и для проверки.

  1.  
  2. //проверим, есть ли в запросе нужные нам поля
  3. if (
  4. isset($_REQUEST['recaptcha_rf']) &&
  5. (!empty($_REQUEST['recaptcha_rf']))
  6. )
  7. {
  8. $recaptcha_challenge_field = trim($_REQUEST['recaptcha_cf']);
  9.  
  10. // то, что вел пользователь
  11. $recaptcha_response_field = trim($_REQUEST['recaptcha_rf']);
  12.  
  13. //Ключи должны быть одинаковыми
  14. //как при отображении формы, так и при проверке
  15. $publickey = "6LfSfQU.......................wfKljellZ";
  16. $privatekey = "6LfSf.........................6IhfsY6jyM";
  17.  
  18. //создаем экземпляр сервиса
  19. $recaptcha = new Zend_Service_ReCaptcha($publickey, $privatekey);
  20.  
  21. //собственно, сама проверка
  22. $result = $recaptcha->verify($recaptcha_challenge_field, $recaptcha_response_field);
  23.  
  24. // Провека
  25. if (!$result->isValid())
  26. {
  27. die ('{success:false,text:"Текст с картинки reCaptcha написан неправильно!"}');
  28. }
  29.  
  30. }

Вот такой пример. Конечно, он не сильно пригоден для прямой вставки в ваш код, мы не стремимся сделать готовое решение доя копи/паста, а скорее показать пути и возможности решения той или иной проблемы.

P.S. Автор идеи и исходного кода - Lizard (lizard.freddi@gmail.com, личный сайт). Текст и редакторская обработка - aleks_raiden (Alpha-Beta-Release Blog).

  • Pingback: Linkdump #10 | CTAPbIu_MABP's BLOG()

  • <<Конечно, он не сильно пригоден для прямой вставки в ваш код
    Но тем не менее спасибо за подробное объяснение как это все работает.

  • demas1982

    штука полезная, но в интерфейсе extjs смотриться отвратительно

    • да нет, отлично смотрится, просто влитое.

  • Арти

    Спасибо за статью. Кстати, на сриншоте у вас кодировка битая.

  • Обалдеть можно! OpenBluePrint не смотря ни на что оказался таки кому-то полезен! Я в шоке 8D

    • да ладно тебе, прибедняешся 😉 полезный проект, однозначно.

Developers.org.ua