google captcha v2

Гугл капча сейчас везде. Плюс ее в том что она заменяет CSRF-токен.

Регистрируем свой домен по ссылке https://www.google.com/recaptcha/admin#list . Получаем ключи. Гугл предоставляет свое мини-апи для запросов на проверку.   Скачать его можно тут https://github.com/vaajnur/recaptcha2

Кстати, если не любите ооп и композер, в конце статьи есть способ проверки капчи всего лишь 3мя строчками кода.

Размещаем на страничке HTML-код капчи с секретным ключом.

Подключаем javascript


<script src='https://www.google.com/recaptcha/api.js'></script>

обработка отправленной капчи


require_once __DIR__ . '/vendor/autoload.php';
// Register API keys at https://www.google.com/recaptcha/admin
$siteKey = '6LdISD0UAAAAAFUfApJZSRqBRuOcfiVdnT31234234';
$secret = '6LdISD0UAAAAAAkYRxJxMYahh70RCVcUn5675675';
// reCAPTCHA supported 40+ languages listed here: https://developers.google.com/recaptcha/docs/language
$lang = 'ru';
if (isset($_POST['g-recaptcha-response'])){
 $recaptcha = new \ReCaptcha\ReCaptcha($secret);
 $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
 if ($resp->isSuccess()):
 ?>
 <h2>Success!</h2>
 <p>That's it. Everything is working. Go integrate this into your real project.</p>
 <p><a href="/">Try again</a></p>
 <?php
 else:
 ?>
 <h2>Something went wrong</h2>
 <?php
 endif;
}

Сама форма

  <form action="" method="post">
 <div class="g-recaptcha" data-sitekey="<?php echo $siteKey; ?>"></div>
 <script type="text/javascript"
 src="https://www.google.com/recaptcha/api.js?hl=<?php echo $lang; ?>">
 </script>
 <br/>
 <input type="submit" value="submit" />
 </form>


Полный код здесь https://github.com/vaajnur/recaptcha2/blob/master/index.php

И пример http://recaptcha.dev10.ru/

Invisible recaptcha

Для этой капчи тоже нужны бэкенд обработчики. Проверка проходит по переменной g-recaptcha-response, которая попадает в post массив , или тот же token в параметрах колбека.

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


<form action="" method="post" id="id_of_form">

  <button
  class="g-recaptcha"
  data-sitekey="<?php echo $siteKey;?>"
  data-callback="onSubmit">
  Submit
</button>


       var onSubmit = function(token) {
         grecaptcha.reset()
       document.getElementById("id_of_form").submit();

     }
</form>

Для ajax капчи добавляем


grecaptcha.render(el, {sitekey: $(el).data('sitekey')});

Ajax + invisible

Добавляем аттрибуты к кнопке сабмита, обязательно колбек. И в самом колбеке делаем аякс запрос

<button  class="g-recaptcha"
  data-sitekey="6LcNqJIUA222AAIrX1xNU__j3Bk3fdgdfg9kcn34tGuU_"
  data-callback="onSubmit" >Отправить заявку</button>

    function onSubmit(token){
          // токен нафиг он нужен, все равно приходит в g-recaptcha-response
        // никаких e.preventDefault();
        $.ajax({
          type: "POST",
          url: "/ajax-handler.php",
          data: $("#form1").serialize(),
          dataType: "json",
          success: function(result) {
            // ресет капчи
            grecaptcha.reset()

Несколько рекаптч на 1 стр.

Подключаем бибил-ку с параметрами


//www.google.com/recaptcha/api.js?onload=onloadRecaptchaCallback&render=explicit

и далее сам колбек. Селектор должен отличаться от привычного g-recaptcha


    function onloadRecaptchaCallback(){
        $('.g-recaptcha123').each(function(ind, el){
            grecaptcha.render(el, {
            'sitekey' : jQuery(el).attr('data-sitekey')
            })
        })
    }

где el это DOM element а не jquery object.
Плюс данного вызова в том что можно выбрать любой селектор, например при открытии модалки аяксом


grecaptcha.render($('.mainform .g-recaptcha123').get(0), { siteKey: $('.g-recaptcha123').data('sitekey') });

навесим обработчик конкретной форме mainform, иначе выдаст ошибку
reCAPTCHA has already been rendered in this element


Ошибки при работе с капчей.

Uncaught Error: reCAPTCHA placeholder element must be empty

Тег капчи не должен содержать вложенных тегов.

ReCAPTCHA couldn’t find user-provided function:

Бывает, что колбек существует, но не биндиться. Решение простое — вынести колбек за $(function), или прочие функции. Колбек должен быть виден напрямую.

recaptcha__ru.js:255 Uncaught (in promise) null 

Здесь ошибка колбека. Попробуйте вызвать grecaptcha.reset() в колбеке.

Uncaught Error: No reCAPTCHA clients exist.

Указанный выше способ — перегенерите капчу. grecaptcha.reset()

render Missing required parameters: sitekey

скорее всего у вас 1-й параметр ф-ии render(el, {}) не dom элемент.

Error: reCAPTCHA has already been rendered in this element
возникает с динамическим контентом. Вешаем колбек правильно, а также ставим таймаут


$(document).on('click', "input[type='submit']", function(){
setTimeout(function(){
grecaptcha.render($('#form-container .g-recaptcha123').get(0), {
sitekey: $('#form-container .g-recaptcha123').eq(0).data('sitekey')
})
}, 1000)
})

Uncaught (in promise) null

в моем случае в колбеке был preventDefault() к-й излишен

А также возможны ошибки бэка

OPENSSL file_get_contents(): Failed to enable crypto

file_get_contents() returns “failed to open stream:

что означает надо включить директивы пхп

allow_url_fopen
allow_url_include

Есть и более простая форма проверки recaptcha.
$recaptcha_secret = '6Leao28UAAAfgfgfMR-6OKq9HBRgfsdkyIBdfXnFA7';
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$recaptcha_secret."&response=".$_POST['g-recaptcha-response']);  
$result = json_decode($response, true); 

Leave a comment

Your email address will not be published.


*