Выдано 112032 лицензии

Капча

Конфигурационный файл

Конфигурационный файл размещается в modules/core/config/captcha.php и содержит следующие настройки:

  • allowedCharacters — строка со списком допустимых символов (алфавит капчи), в стандартной поставке указываются только цифры;
  • color — массив с цветами RGB, по умолчанию не указывается и генерируется случайно;
  • backgroundColor — массив с цветами фона RGB, по умолчанию не указывается и генерируется случайно;
  • noise — уровень шума, по умолчанию 10;
  • width — ширина капчи, по умолчанию 88;
  • height — высота капчи, по умолчанию 31;
  • minLenght — минимальная длина капчи, по умолчанию 4;
  • maxLenght — максимальная длина капчи, по умолчанию 4;
  • fillBackground — использовать фон, по умолчанию TRUE.
<?php

return array (
	'allowedCharacters' => '1234567890', // 23456789abcdeghkmnpqsuvxyz
	//'color' => array(0, 0, 0),
	//'backgroundColor' => array(255, 255, 255),
	//'noise' => 10,
	//'width' => 88,
	//'height' => 31,
	'minLenght' => 4,
	'maxLenght' => 4,
	'fillBackground' => TRUE,
);

Повышение сложности капчи

В список допустимых символов вместо цифр добавьте буквы, также используйте капчу переменной длины, например:

<?php

return array (
	'allowedCharacters' => '23456789abcdeghkmnpqsuvxyz',
	'noise' => 20,
	'minLenght' => 4,
	'maxLenght' => 6,
	'fillBackground' => TRUE,
);

Замена стандартной капчи на Google reCaptcha в формах модуля "Формы"

Рассмотрим пример замены капчи для модуля форм.

Получение регистрационных данных

  1. Перейдите на страницу reCAPTCHA
  2. Заполните форму "Регистрация сайта". Например,

  3. После нажатия кнопки "Регистрация" произойдет переход на страницу с регистрационными данными. Необходима будет пара Ключ + Секретный ключ:

Интеграция на стороне клиента

Вставьте этот фрагмент перед закрывающим тегом </head> в HTML-коде:

<script src="https://www.google.com/recaptcha/api.js" type="text/javascript"></script>

Интеграция на стороне сервера

В XSL-шаблон в тег <form> вносим строку виджета каптчи там, где нуден показ:

<div class="g-recaptcha" data-sitekey="{/form/site_key}"></div>

Когда пользователи отправляют форму со встроенной проверкой reCAPTCHA, вместе с прочими данными вы получаете строку "g-recaptcha-response". Чтобы узнать, прошел ли пользователь проверку, отправьте POST-запрос. Если получили успешный ответ, то форма отправляется.

if (Core::moduleIsActive('form'))
{
    $oForm = Core_Entity::factory('Form', Core_Array::get(Core_Page::instance()->libParams, 'formId'));

    $Form_Controller_Show = new Form_Controller_Show($oForm);

    $xslName = Core_Array::get(Core_Page::instance()->libParams, 'formXsl');
    
    $sSecretKey = "xxx"; // Указывается секретный ключ reCAPTCHA

    if (!is_null(Core_Array::getPost($oForm->button_name)))
    {
        if (Core_Array::getPost('g-recaptcha-response'))
        {
            $sResponse = Core_Array::getPost('g-recaptcha-response');

            $sUrl = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $sSecretKey . "&response=" . $sResponse;    
            $Core_Http = Core_Http::instance('curl')
            ->clear()
            ->method('POST')
            ->url($sUrl)
            ->execute();

            $aAnswer = json_decode($Core_Http->getBody(), TRUE);            
            
            if ($aAnswer['success'])
            {
                $Form_Controller_Show
                    ->values($_POST + $_FILES)
                    // 0 - html, 1- plain text
                    ->mailType(Core_Array::get(Core_Page::instance()->libParams, 'mailType'))
                    ->mailXsl(
                        Core_Entity::factory('Xsl')->getByName(Core_Array::get(Core_Page::instance()->libParams, 'notificationMailXsl'))
                    )
                    ->mailFromFieldName(Core_Array::get(Core_Page::instance()->libParams, 'emailFieldName'))
                    ->process();
            }
            else
            {
               Core_Log::instance()->clear()
                ->status(Core_Log::$ERROR)
                ->write('Google Recaptcha: ' . $aAnswer['error-codes'][0]);
            }    
        }            
    }

    $Form_Controller_Show
        ->xsl(
            Core_Entity::factory('Xsl')->getByName($xslName)
        )
        ->addEntity(
            Core::factory('Core_Xml_Entity')
                ->name('site_key')->value('yyy') // Указываете ключ reCAPTCHA
        )
        ->show();
}

Замена стандартной капчи на Google reCaptcha в комментариях

Рассмотрим пример замены капчи для комментариев магазина. Для комментариев информационных систем точно такой же алгоритм.

Получение регистрационных данных

  1. Производим стандартную регистрацию сайта.Перейдите на страницу reCAPTCHA
  2. Заполните форму "Регистрация сайта". Например,

  3. После нажатия кнопки "Регистрация" произойдет переход на страницу с регистрационными данными. Необходима будет пара Ключ + Секретный ключ:

Интеграция на стороне клиента

1. Если у вас стандартные комментарии системы, то вставьте этот фрагмент перед закрывающим тегом </head> в HTML-коде, указав вместо your_key ключ сайта, который был получен ранее:

<script type="text/javascript">
    var CaptchaCallback = function(){
        $('.g-recaptcha').each(function(index, el) {
            grecaptcha.render(el, {'sitekey' : 'your_key'});
        });
    };
</script>

<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>

2. Если у вас комментарии без возможности ответов на уже добавленные комментарии, т.е. форма комментариев одна на странице, то вставьте этот фрагмент перед закрывающим тегом </head> в HTML-коде:

<script src="https://www.google.com/recaptcha/api.js" type="text/javascript"></script>

Интеграция на стороне сервера

В XSL-шаблоне карточки товара, в темлейт формирующий форму комментариев, в тег <form> вносим строку виджета каптчи там, где нужен показ:

<!-- Showing captcha -->
<xsl:if test="/shop/use_captcha = 1 and /shop/siteuser_id = 0">
    <div class="g-recaptcha" data-sitekey="{/shop/site_key}"></div>
</xsl:if>

Когда пользователи отправляют форму со встроенной проверкой reCAPTCHA, вместе с прочими данными вы получаете строку "g-recaptcha-response". Чтобы узнать, прошел ли пользователь проверку, отправьте POST-запрос. Если получили успешный ответ, то форма отправляется.

Переходим в типовую динамическую страницу магазина и настраиваем её на обработку reCAPTCHA:

  1. В коде типовой динамической страницы, после $Shop_Controller_Show = Core_Page::instance()->object; добавляем передачу в XML ключа reCAPTCHA, который был получен при регистрации в Google reCaptcha.
    // Google reCaptcha
    $Shop_Controller_Show->addEntity(
        Core::factory('Core_Xml_Entity')
            ->name('site_key')->value('yyy') // Указываете ключ reCAPTCHA
    );
  2. Следующий шаг - замена стандартной обработки капчи. Для этого блок:
    if (Core_Array::getPost('add_comment') && Core_Array::get(Core_Page::instance()->libParams, 'showComments', 1))
    {
        ...
    }

    заменяется на:

    if (Core_Array::getPost('add_comment') && Core_Array::get(Core_Page::instance()->libParams, 'showComments', 1))
    {
        $oShop = $Shop_Controller_Show->getEntity();

        $sSecretKey = "xxx"; // Указывается секретный ключ reCAPTCHA

        $Shop_Controller_Show->cache(FALSE);

        $oLastComment = Core_Entity::factory('Comment')->getLastCommentByIp(
            Core_Array::get($_SERVER, 'REMOTE_ADDR')
        );

        $oXmlCommentTag = Core::factory('Core_Xml_Entity')
            ->name('document');

        $siteuser_id = 0;
        if (Core::moduleIsActive('siteuser'))
        {
            $oSiteuser = Core_Entity::factory('Siteuser')->getCurrent();

            if ($oSiteuser)
            {
                $siteuser_id = $oSiteuser->id;
            }
        }

        $oComment = Core_Entity::factory('Comment');

        $allowable_tags = '<b><strong><i><em><br><p><u><strike><ul><ol><li>';
        $oComment->parent_id = intval(Core_Array::getPost('parent_id', 0));
        $oComment->active = $oShop->comment_active;
        $oComment->author = Core_Str::stripTags(Core_Array::getPost('author'));
        $oComment->email = Core_Str::stripTags(Core_Array::getPost('email'));
        $oComment->phone = Core_Str::stripTags(Core_Array::getPost('phone'));
        $oComment->grade = intval(Core_Array::getPost('grade', 0));
        $oComment->subject = Core_Str::stripTags(Core_Array::getPost('subject'));
        $oComment->text = nl2br(Core_Str::stripTags(Core_Array::getPost('text'), $allowable_tags));
        $oComment->siteuser_id = $siteuser_id;

        $oShop_Item = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item);

        $oXmlCommentTag
            ->addEntity($oComment)
            ->addEntity($oShop_Item);

        if (is_null($oLastComment) || time() > Core_Date::sql2timestamp($oLastComment->datetime) + ADD_COMMENT_DELAY)
        {
            if (Core_Array::getPost('g-recaptcha-response'))
            {
                $sResponse = Core_Array::getPost('g-recaptcha-response');

                $sUrl = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $sSecretKey . "&response=" . $sResponse;

                $Core_Http = Core_Http::instance('curl')
                ->clear()
                ->method('POST')
                ->url($sUrl)
                ->execute();

                $oAnswer = json_decode($Core_Http->getBody());

                if ($oAnswer->success)
                {
                    $oComment->save();

                    $oComment
                        ->dateFormat($oShop->format_date)
                        ->dateTimeFormat($oShop->format_datetime);

                    $oShop_Item->add($oComment)->clearCache();

                    $oXmlCommentTag->addEntity($oShop);

                    // Отправка письма администратору
                    $sText = Xsl_Processor::instance()
                        ->xml($oXmlCommentTag->getXml())
                        ->xsl(Core_Entity::factory('Xsl')->getByName(Core_Array::get(Core_Page::instance()->libParams, 'addCommentAdminMailXsl')))
                        ->process();

                    $aFrom = array_map('trim', explode(',', EMAIL_TO));

                    Core_Mail::instance()
                        ->to(EMAIL_TO)
                        ->from($aFrom[0])
                        ->header('Reply-To', Core_Valid::email($oComment->email)
                            ? $oComment->email
                            : $aFrom[0]
                        )
                        ->subject(Core::_('Shop.comment_mail_subject'))
                        ->message(trim($sText))
                        ->contentType(Core_Array::get(Core_Page::instance()->libParams, 'commentMailNoticeType', 0) == 0
                            ? 'text/plain'
                            : 'text/html'
                        )
                        ->send();
                }
                else
                {
                    Core_Log::instance()->clear()
                    ->status(Core_Log::$ERROR)
                    ->write($oAnswer->error-codes);

                    $oXmlCommentTag->addEntity(Core::factory('Core_Xml_Entity')
                        ->name('error_captcha')->value(1)
                    );

                    $oComment->text = Core_Str::br2nl($oComment->text);
                    $Shop_Controller_Show->addEntity($oComment);
                }
            }
            else
            {
                $oXmlCommentTag->addEntity(Core::factory('Core_Xml_Entity')
                    ->name('error_captcha')->value(1)
                );

                $oComment->text = Core_Str::br2nl($oComment->text);
                $Shop_Controller_Show->addEntity($oComment);
            }
        }
        else
        {
            $oXmlCommentTag->addEntity(Core::factory('Core_Xml_Entity')
                ->name('error_time')->value(1)
            );

            $oComment->text = Core_Str::br2nl($oComment->text);
            $Shop_Controller_Show->addEntity($oComment);
        }

        // Результат добавления комментария
        $xsl_result = Xsl_Processor::instance()
            ->xml($oXmlCommentTag->getXml())
            ->xsl(Core_Entity::factory('Xsl')->getByName(
                Core_Array::get(Core_Page::instance()->libParams, 'addCommentNoticeXsl'))
            )
            ->process();

        $Shop_Controller_Show->addEntity(
            Core::factory('Core_Xml_Entity')
                ->name('message')->value($xsl_result)
        );
    }

    где в переменной $sSecretKey указывается секретный ключ, который был получен вместе с ключом сайт при регистрации в Google reCAPTCHA.

Возможные ошибки

  • При получении ошибки Exception: The property '_login' does not exist in the model 'lib' необходимо заменить:
    $Core_Http = Core_Http::instance('curl')
    ->clear()
    ->method('POST')
    ->url($sUrl)
    ->execute();

    $oAnswer = json_decode($Core_Http->getBody());
    на:
    $oAnswer = json_decode(file_get_contents($sUrl));

Не нашли ответ на свой вопрос в документации? Направьте обращение в или онлайн чат.

Комментарии

  • Rewired

    Введен неверный код подтверждения!

    Все сделал по инструкции для комментариев ИС, но система выдает ошибку Введен неверный код подтверждения! Галочка на рекапче проставляется, но все равно неверный код. С формами все работает отлично, а вот с комментами облом. Версия HostCMS: 6.7.4.

    11.09.2017 12:21:57 Rewired

    Без темы

    Обратитесь,пожалуйста, по данному вопросу в техническую поддержку https://www.hostcms.ru/support/

    11.09.2017 12:51:14 llirik
  • Показ ошибки

    Внедрил код в форму обратной связи. Если галочка в reCaptcha стоит, то всё отправляется и выводится сообщение подтверждения. Если галочка не проставлена - запрос проверки reCaptcha отправляется, но никакого сообщения об ошибке не выводится. Само сообщение, не отправляется.

    13.07.2017 15:04:04 iNik
  • Rewired

    Без темы

    А не подскажите как встроить невидимую reCaptcha?

    13.04.2017 11:54:19 Rewired
  • Регистрация

    как поправить тдс регистрации пользователя чтоб рекапчёй от гугля защитить форму от спамеров?

    01.04.2017 05:29:37 kvasiliy
  • ошибка

    после внедрения рекапчи в комментарии магазина если отметку не делать то просто страница перезагружается. А сли отметить галочкой "Я не робот" система выдаёт ошибку:Exception: The property '_login' does not exist in the model 'lib'
    35 modules/core/exception.php
    1239 modules/core/orm.php
    163 modules/core/log.php
    384 hostcmsfiles/lib/lib_52/lib_52.php
    271 modules/lib/model.php
    138 modules/core/page.php
    22 templates/template173/template.htm
    86 modules/template/model.php
    138 modules/core/page.php
    180 templates/template85/template.htm
    86 modules/template/model.php
    138 modules/core/page.php
    417 modules/core/command/controller/default.php
    190 modules/core/router/route.php
    242 index.php

    14.03.2017 07:12:58 kvasiliy

    Без темы

    Направьте запрос в поддержку с данными доступа в ЦА и страницей с капчей. Посмотрим в чем может быть проблема.

    14.03.2017 09:12:43 alexander.egorov
  • Повышение сложности капчи и Google reCaptcha

    1. Используя советы, указанные в параграфе "Повышение сложности капчи", получил не очень хорошие результаты - увеличение максимальной длины капчи и уровня шума приводит к нечитаемости капчи живыми людьми, как уж справятся с этим роботы не знаю, но применять указанные советы невозможно - заполнить форму не смогут люди...

    2. Прошу прощения, а указанный фрагмент (if (Core::moduleIsActive('form')) и далее...) для Google reCaptcha куда необходимо добавить, если необходимо защитить с помощью этой технологии комментарии в магазине или ИС?

    04.02.2017 02:02:43 yestravel

    Без темы

    Это был пример для форм из модуля формы. Добавлен пример для комментариев магазина и ИС.

    08.02.2017 09:45:03 alexander.egorov
    zuhizugo

    Замена стандартной капчи на Google reCaptcha в комментариях информационной системы

    Здравствуйте!

    Попробывали сделать для ИС, для одной формы комментария, все сделано по аналогии, версия 6.7.0

    При попытке запостить, если вообще не трогать рекапчу, система пишет об удачном добавлении, естественно коммент не добавляется. А должно быть уведомление о том что капча не введена


    25.03.2017 13:49:36 zuhizugo