Google Recaptcha V3 + ajax

#
Google Recaptcha V3 + ajax
Здравствуйте товарищи. Хочу написать как сделать рекапчу v3 в связке с ajax для отправки форм методом $oCore_Mail_Driver.
Как получить ключи достаточно подробно написано тут: https://www.hostcms.ru/documentation/modules/core/captcha/
Теперь наступает самое интересное:
часть серверная, располагается в главном макете, на самом верху над <!DOCTYPE html>

<?php
$sSecretKey = "Секретный ключ сайта";
if (!is_null(Core_Array::getPost('feedback-submit')))   {
   $form_name = Core_Array::getPost('name');
   $form_email = Core_Array::getPost('email');
   $form_comment = Core_Array::getPost('comment');

   $message .= 'Имя: '.$form_name."\r\n\r\n";
   $message .= 'Email: '.$form_email."\r\n\r\n";
   $message .= 'Сообщение: '.$form_comment."\r\n\r\n";
   $form_subject = 'Заполнена форма с сайта';
   
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());
   
var_dump($oAnswer);
   
if ($oAnswer->success && $oAnswer->score >= 0.6)
{
         $oCore_Mail_Driver = Core_Mail::instance()
        ->to(EMAIL_TO)
    ->from('no-reply@ваш_сайт.ru') // <-можно указать отправителя, а можно не указывать
     ->subject($form_subject)
        ->message(trim($message))
        ->contentType('text/plain')
        ->send();
         $result = array('status' => true, 'message' => 'ok');
         echo json_encode($result);    
         exit();
      }
    else
    {
    Core_Log::instance()->clear()
     ->status(Core_Log::$ERROR)
     ->write($oAnswer->{'error-codes'});
    }  
   }   
}
?>

Далее интеграция на стороне клиента
<script src='https://www.google.com/recaptcha/api.js?render=публичный_ключ_сайта' async="async" defer="defer"></script>
и добавляем можно в script.js можно просто в <script></script>

document.addEventListener("DOMContentLoaded", () => {
grecaptcha.ready(function () {
grecaptcha.execute('публичный_ключ_сайта', {
   action: 'send_letter'
   }).then(function(token) {
// добавляем токен в форму
//для проверки токена можно вывести в console.log(token);
$('form').append('<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
$('form').append('<input type="hidden" name="feedback-submit" value="feedback-submit">'); //тут должно быть name из: getPost('feedback-submit')
});
});

далее идет уже обычный ajax

$('form').submit(function() {
event.preventDefault();
   formData = $(this).closest("form").serializeArray();
$.ajax({
            type: "POST",
            dataType: 'html',
            url: './',
            data: formData, // serializes the form's elements.
            success: function(data){
   // Обработка success   
$('#success').alert("Все ок!");   
   },
   error: function(data) {
      //Обработка error
$('#success').alert("Все не ок!");   
            }
});    
});

В общем после этих манипуляций, все отправляется ajax запросом с прохождением проверки recaptcha v3. Предупреждаю сразу, паста кода может не заработать, т.к. надо проверять значения полей и допиливать под свой код.
В говно может вступить любой желающий. (с)
#
Re: Google Recaptcha V3 + ajax
Единственный момент еще не разобрался почему если делать через ТДС Формы например
<?php
if (Core::moduleIsActive('form'))
{
   $sSecretKey = Core_Array::get(Core_Page::instance()->libParams, 'SecretKey');
   
   $oForm = Core_Entity::factory('Form', Core_Array::get(Core_Page::instance()->libParams, 'formId'));

   $Form_Controller_Show = new Form_Controller_Show($oForm);

   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();

$oAnswer = json_decode($Core_Http->getDecompressedBody());
      if ($oAnswer->success && $oAnswer->score >= 0.6)
{   
      $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();

   $result = array('status' => true, 'message' => 'ok');
   echo json_encode($result);    
   exit();
      }
         else {
         Core_Log::instance()->clear()
     ->status(Core_Log::$ERROR)
     ->write($oAnswer->{'error-codes'});
         }
      }
      else
{
  $Form_Controller_Show->addEntity(
  Core::factory('Core_Xml_Entity')
  ->name('errorId')
  ->value(0)
  );
}
   }

Core_Page::instance()->object = $Form_Controller_Show;
}
респонс приходит 'status' => true, 'message' => 'ok' но письмо не приходит на ящик и в заполненные формы не падает.
Товарищи разработчики, подскажите где логи посмотреть?
В говно может вступить любой желающий. (с)
#
Re: Google Recaptcha V3 + ajax
Rewired,
вероятно срабатывает проверка на стандартную каптчу?
HostDev.pw - модули для HostCMS, Telegram: @hostdev
#
Re: Google Recaptcha V3 + ajax
Да, действительно срабатывала проверка на обычную капчу, но в коде ТДС нет ни слова о капче.
В говно может вступить любой желающий. (с)
#
Re: Google Recaptcha V3 + ajax
Rewired,
в контроллере показа формы Form_Controller_Show происходит проверка на штатную каптчу
HostDev.pw - модули для HostCMS, Telegram: @hostdev
#
Re: Google Recaptcha V3 + ajax
Рабочий вариант recaptcha v3 + ajax (рабочий вариант на данный момент)
серверная часть php:

$sSecretKey = "ваш секретный ключ recatpcha";

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(), true);
   
if ($oAnswer["score"] >= 0.5)
{
// Данные формы
        $form_name = Core_Array::getPost('name');
   $form_email = Core_Array::getPost('email');
   $form_text = Core_Array::getPost('message');

    // Тема
    $form_subject = 'Тема';
    $message = null;
    // Собираем сообщение
   $message .= 'Имя: '.$form_name."\r\n\r\n";
   $message .= 'Email: '.$form_email."\r\n\r\n";
   $message .= 'Сообщение: '.$form_text."\r\n\r\n";
      
   $oCore_Mail_Driver = Core_Mail::instance()
    ->to('rz300@ya.ru')
    ->from('no.reply@host.ru')
    ->subject($form_subject)
    ->message(trim($message))
    ->contentType('text/plain')
    ->header('Precedence', 'bulk')
    ->send();
    
   $result = array('status' => true, 'message' => 'ok','result' => 'success');

    echo json_encode($result);
    
   exit();
}
}

добавляем в <head>
<script src='https://www.google.com/recaptcha/api.js?render=публичный ключ рекапчи' async="async" defer="defer"></script>

код javascript

grecaptcha.ready(function () {
grecaptcha.execute('публичный ключ рекапчи', {
   action: 'send'
   }).then(function(token) {
// add token to form
$('.formCallBack').prepend('<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
});   
});

     $('.formCallBack').submit(function() {
      var data = $(this).serializeArray();
      $.ajax({
         type: 'post',
         url: './',
         data: data,
         dataType: 'html',
         success: function(e) {
            //console.log(true);
            $('.formCallBack').html('<p>Ваша заявка отправлена, спасибо!</p>');
            $('.formCallBack .btn').css('display', 'none');
         },
         error: function(e) {
            console.log(false);
         }
      });
      return false;
   });  


Пробуйте в своих проектах, должно работать
В говно может вступить любой желающий. (с)
Авторизация