Установка и настройка Google reCAPTCHA v3 для PHP сайта


16-04-2019
Денис Л.
Разное
10
6849
Установка и настройка Google reCAPTCHA v3 для PHP сайта

Для того, чтобы установить Google reCAPTCHA v3 на сайт, первым делом заходим на официальный сайт Google reCAPTCHA v3 и получаем ключи. Описывать этот процесс не буду, всё интуитивно понятно и легко.

Нам понадобятся 2 вида ключей:

  1. Открытый ключ, который мы будем использовать на стороне сайта в функциях JavaScript;
  2. Закрытый ключ, который мы будем использовать на стороне сервера (в нашем случае, обрабатывать будем с помощью PHP).

Затем, в область <head> нашего сайта добавляем строку:

<script src="https://www.google.com/recaptcha/api.js?render=ВАШ_ОТКРЫТЫЙ_КЛЮЧ"></script>

При создании формы в html-коде создайте скрытое поле ввода для предварительного отсева большинства spam-ботов, которые будут заполнять его, и мы будем отсекать их при первой же проверке на нашем сервере. Например вот так:

<input name="surname" hidden>

Следующим шагом в нашем файле со скриптами JavaScript создадим ajax обработчик нашей формы. Для примера давайте представим, что у нашей формы есть поля, в которые мы просим клиента вставить:

имя, название организации, телефон, e-mail, комментарии.

Также, для простоты допустим, что на нашем сайте установлена библиотека jQuery. Если Ваш сайт без jQuery - используйте стандартный вариант XMLHttpRequest и обращайтесь к форме через document.querySelector. Это стандартные практики, не буду описывать.

$('form').on('submit', function(e) { // при попытке отправить форму
    e.preventDefault(); // останавливаем стандартный обработчик события отправки формы
    // затем ниже создаём переменные, в которые получаем введённые пользователем значения
    var form     = $(this); //console.log(form);
    var action   = form.attr('action'); //console.log(action);
    var surname  = form.find('[name="surname"]').val(); //console.log(surname);
    var name     = form.find('[name="name"]').val(); //console.log(name);
    var ooo      = form.find('[name="ooo"]').val(); //console.log(ooo);
    var tel      = form.find('[name="tel"]').val(); //console.log(tel);
    var email    = form.find('[name="email"]').val(); //console.log(email);
    var comments = form.find('[name="comments"]').val(); //console.log(comments);
    grecaptcha.ready(function () { // по готовности скриптов recaptcha
        grecaptcha.execute('ВАШ_ОТКРЫТЫЙ_КЛЮЧ', {
            action: 'sendform' // этот параметр не имеет значения
        })
        .then(function(token) {
            $.ajax({ // отправляем информацию на сервер
                url: action,
                type: 'POST',
                data: ({
                    surname:  surname,
                    name:     name,
                    ooo:      ooo,
                    tel:      tel,
                    email:    email,
                    comments: comments,
                    token:    token
                }),
                success: function(result) { // если всё хорошо отправилось
                    yaCounter47438980.reachGoal('formSubmit');
                    console.log('форма отправлена');
                    alert('Форма успешно отправлена');
                },
                error: function(result) { // если была ошибка в процессе отправки
                    console.log('ОШИБКА');
                    // console.log(result);
                    alert('Произошла ошибка при отправке формы');
                }
            });
        });
    });
});

Теперь создаём на PHP файл с обработчиком данных (на этот файл мы должны ссылаться в атрибуте action нашей формы).

<?php

$spam     = $_POST["surname"];  // получаем данные из нашего скрытого поля
$name     = htmlspecialchars(trim($_POST["name"])); // имя клиента
$ooo      = htmlspecialchars(trim($_POST["ooo"])); // название организации
$tel      = htmlspecialchars($_POST["tel"]); // телефон
$email    = htmlspecialchars($_POST["email"]); // e-mail
$comments = htmlspecialchars($_POST["comments"]); // комментарии
$today    = date('j.n.Y H:m'); // текущая дата

$url_google_api = 'https://www.google.com/recaptcha/api/siteverify';
$secret = 'ЗДЕСЬ_ВАШ_СЕКРЕТНЫЙ_КЛЮЧ';
$query = $url_google_api.'?secret='.$secret.'&response='.$_POST['token'].'&remoteip='.$_SERVER['REMOTE_ADDR'];
$data = json_decode(file_get_contents($query), true); // записываем полученные данные в виде ассоциативного массива
$score = $data['score']; // оценка Google recaptcha v3, от 0.1 до 0.9, где 0.9 означает "точно не спам"

if( empty($spam) && !preg_match("/[a-z0-9]/i", $name) ) { // если поле spam пустое и если в имени нет цифр и латиницы

    $to = "ВАШ_E-MAIL"; // если нужно указать несколько e-mail, указываем через запятую, внутри двойных кавычек
    $from = "E-MAIL_С_КОТОРОГО_ДОЛЖНО_ПРИХОДИТЬ_СООБЩЕНИЕ";
    $subject = "У Вас вопрос с сайта НАЗВАНИЕ_ВАШЕГО_САЙТА";
    $message = "<b>Имя клиента: </b>{$name}<hr>"."\n"."<b>Название организации: </b>{$ooo}<hr>"."\n"."<b>Телефон: </b>{$tel}<<r>"."\n"."<b>E-mail: </b>{$email}<hr>"."\n"."<b>Комментарии: </b>{$comments}<hr>"."\n";
    $subject = "=?utf-8?B?".base64_encode($subject)."?=";
    $headers = "From: $from\r\nReply-to: $from\r\nContent-type: text/html; charset=utf-8\r\n";

    $logText = strip_tags($message); // готовим запись логов

    if($data['success']) { // если ответ от сервиса Google был получен в нём есть input-response
        if($score >= 0.5) { // если оценка на spam больше чем 0.5 (Вы можете менять это на своё усмотрение)
            $logFile = "mail.log"; chmod($logFile, 0600); // формируем лог-файл с правами 0600
            file_put_contents($logFile, "\n{$today}\n{$logText}\n", FILE_APPEND); // записываем информацию в лог-файл
            mail($to, $subject, $message, $headers); // отправляем письмо
        }
        else { // если оценка на spam меньше чем 0.5
            $spamLog = "spam.log"; chmod($spamLog, 0600); // формируем лог-файл для спама, с правами 0600
            // это нужно, чтобы исключить ошибки отсева и отследить корректность нашей оценки (0.5 или выше)
            file_put_contents($spamLog, "\n{$today}\n{$logText}Запрос: {$query}\nScore: {$score}\n", FILE_APPEND);
            $message .= "<b>Это письмо попало в спам</b>"; 
            mail("E-MAIL_АДРЕС_ВЕБ-РАЗРАБОТЧИКА", $subject, $message, $headers);
            exit();
        }
    }
    
}
else { 
    exit();
}

P.S. Если у Вас что-то не работает - сначала раскомментируйте все выводы в консоль в файле с JavaScript, затем проверьте, что у Вас на сервере включена функция php_value allow_url_fopen (стоит значение On). Если не работает - либо включите её через файл php.ini, либо пропишите в файл .htaccess строку php_value allow_url_fopen On, либо обратитесь к Вашему хостинг-провайдеру с просьбой включить эту функцию.

Подписывайтесь на группу в ВКонтакте, вступайте в сообщество на Facebook, чтобы всегда быть в курсе актуальных выпусков
Web development blog!

Читайте также:

Пишем свой css фреймворк на Sass

Как подключить чат в поиске Яндекса + крутой онлайн чат для сайта

Пишем функцию лайков для постов блога