Капча
Конфигурационный файл
Конфигурационный файл размещается в 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 в формах модуля «Формы»
Рассмотрим пример замены капчи для модуля форм.
Получение регистрационных данных
- Перейдите на страницу reCAPTCHA
- Заполните форму «Регистрация сайта». Например,
- После нажатия кнопки «Регистрация» произойдет переход на страницу с регистрационными данными. Необходима будет пара Ключ + Секретный ключ:
Интеграция на стороне клиента
Вставьте этот фрагмент перед закрывающим тегом </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';
$Core_Http = Core_Http::instance('curl')
->clear()
->method('POST')
->url($sUrl)
->additionalHeader('Accept-Encoding', 'gzip, deflate')
->data('secret', $sSecretKey)
->data('response', $sResponse)
->execute();
$aAnswer = json_decode($Core_Http->getDecompressedBody(), 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]);
}
}
else
{
$Form_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('errorId')
->value(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 в комментариях
Рассмотрим пример замены капчи для комментариев магазина. Для комментариев информационных систем точно такой же алгоритм.
Получение регистрационных данных
- Производим стандартную регистрацию сайта.Перейдите на страницу reCAPTCHA
- Заполните форму «Регистрация сайта». Например,
- После нажатия кнопки «Регистрация» произойдет переход на страницу с регистрационными данными. Необходима будет пара Ключ + Секретный ключ:
Интеграция на стороне клиента
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:
- В коде типовой динамической страницы, после
$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
); - Следующий шаг — замена стандартной обработки капчи. Для этого блок:
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';
$Core_Http = Core_Http::instance('curl')
->clear()
->method('POST')
->url($sUrl)
->additionalHeader('Accept-Encoding', 'gzip, deflate')
->data('secret', $sSecretKey)
->data('response', $sResponse)
->execute();
$oAnswer = json_decode($Core_Http->getDecompressedBody());
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)
->additionalHeader('Accept-Encoding', 'gzip, deflate')
->data('secret', $sSecretKey)
->data('response', $sResponse)
->execute();
$oAnswer = json_decode($Core_Http->getDecompressedBody());$oAnswer = json_decode(file_get_contents($sUrl));
Комментарии
-
Captcha в корзине
Добрый день! Подскажите, как добавить проверку каптчи в корзине?
Такую же проверку, как в формах
// нажали кнопку - получаем данные из формы и сохраняем их
if ($this->captcha == 0 || Core_Captcha::valid(Core_Array::getPost('captcha_id'), Core_Array::getPost('captcha'))) {....
-
Вариант использования капчи от Гугл
На сколько я понял, за проверку капчи отвечает вот это:
if ($oShop->use_captcha == 0 || $siteuser_id > 0 || Core_Captcha::valid(Core_Array::getPost('captcha_id'), Core_Array::getPost('captcha')))
{
А если вот это:
Core_Captcha::valid(Core_Array::getPost('captcha_id'), Core_Array::getPost('captcha'))
заменить на результат функции например:
function answer(){
$sSecretKey = "xxx"; // Указывается секретный ключ reCAPTCHA
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;
$aAnswer = json_decode(file_get_contents($sUrl), TRUE);
if ($aAnswer['success'])
{
return TRUE;
}
else
{
Core_Log::instance()
->clear()
->status(Core_Log::$ERROR)->write('Google Recaptcha: ' . $aAnswer['error-codes'][0]);
}
}
}
и уже потом
if (]if ($oShop->use_captcha == 0 || $siteuser_id > 0 || answer())
{
Насколько жизнеспособен такой вариант?
PS Вне зависимости от того, магазин это, ИС или регистрация пользователя.
-
HTTP/1.0 411 Length Required
Настроил. Получил ошибку HTTP/1.0 411 Length Required.
Работает после замены метода с GET на POST:
$Core_Http = Core_Http::instance('curl')
->clear()
->method('GET')
->url($sUrl)
->execute();
Работает после замены метода с GET на POST
Аналогичная ситуация, весь код, как с листа, заработало только после замены POST на GET, до того проходила проверку, но не обрабатывала форму.
-
Замена стандартной капчи на Google reCaptcha в формах модуля "Формы"
При отправке комментария в карточке товара получаем такую ошибку:
Замечание: Trying to get property 'success' of non-object в файле...
Undefined error: Non-static method Core_Log::write() should not be called statically в файле...
Замечание: Trying to get property 'error' of non-object в файле... (строка 405)Предупреждение: Use of undefined constant codes - assumed 'codes' (this will throw an Error in a future version of PHP) в файле ... (строка 405)Предупреждение: A non-numeric value encountered в файле ... (строка 405)Exception: Using $this when not in object contextЗамена стандартной капчи на Google reCaptcha в формах модуля "Формы"
Похоже вы используете устаревший код, замените его кодом из текущей документации.
Без темы
Код заменил. Ошибка
Замечание: Trying to get property 'success' of non-object в файле ... (строка 368)Замечание: Trying to get property 'error-codes' of non-object в файле ... (строка 407)
Это стоки :
if ($oAnswer->success)
и
Core_Log::instance()->clear()
И сообщение:
Ошибка! Вы неверно ввели число подтверждения отправки комментария!
-
Без темы
Опечатка:
Core_Log::instance()->clear()
->status(Core_Log::$ERROR)
->write($oAnswer->error-codes);Без темы
Уточните, в чем именно опечатка?
Без темы
Если $oAnswer — это объект и у него есть свойство 'error-codes', то получить его значение можно вот так: $oAnswer->{'error-codes'}, иначе неправильно разбирается интерпретатором.
-
Введен неверный код подтверждения!
Все сделал по инструкции для комментариев ИС, но система выдает ошибку Введен неверный код подтверждения! Галочка на рекапче проставляется, но все равно неверный код. С формами все работает отлично, а вот с комментами облом. Версия HostCMS: 6.7.4.
Без темы
Обратитесь,пожалуйста, по данному вопросу в техническую поддержку https://www.hostcms.ru/support/
-
Показ ошибки
Внедрил код в форму обратной связи. Если галочка в reCaptcha стоит, то всё отправляется и выводится сообщение подтверждения. Если галочка не проставлена - запрос проверки reCaptcha отправляется, но никакого сообщения об ошибке не выводится. Само сообщение, не отправляется.
-
Регистрация
как поправить тдс регистрации пользователя чтоб рекапчёй от гугля защитить форму от спамеров?
-
ошибка
после внедрения рекапчи в комментарии магазина если отметку не делать то просто страница перезагружается. А сли отметить галочкой "Я не робот" система выдаёт ошибку: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Без темы
Направьте запрос в поддержку с данными доступа в ЦА и страницей с капчей. Посмотрим в чем может быть проблема.
-
Повышение сложности капчи и Google reCaptcha
1. Используя советы, указанные в параграфе "Повышение сложности капчи", получил не очень хорошие результаты - увеличение максимальной длины капчи и уровня шума приводит к нечитаемости капчи живыми людьми, как уж справятся с этим роботы не знаю, но применять указанные советы невозможно - заполнить форму не смогут люди...
2. Прошу прощения, а указанный фрагмент (if (Core::moduleIsActive('form')) и далее...) для Google reCaptcha куда необходимо добавить, если необходимо защитить с помощью этой технологии комментарии в магазине или ИС?Без темы
Это был пример для форм из модуля формы. Добавлен пример для комментариев магазина и ИС.
Замена стандартной капчи на Google reCaptcha в комментариях информационной системы
Здравствуйте!
Попробывали сделать для ИС, для одной формы комментария, все сделано по аналогии, версия 6.7.0
При попытке запостить, если вообще не трогать рекапчу, система пишет об удачном добавлении, естественно коммент не добавляется. А должно быть уведомление о том что капча не введена