Пошаговая инструкция по интеграции reCaptcha V3 во Vue.js проект

Всем привет. Сегодня мы научимся ставить Google reCaptcha V3 на Vue.js сайт. Кстати, инструкция подойдет даже для обычных сайтов, например, написанных на PHP.

Все очень легко, даже не знаю зачем кому-то нужна эта статья...но спрос есть, плюс мне хочется размять свой мозг написанием какого-нибудь полезного стаффа для молодых программистов. Обещаю, все будет понятно.

Дисклеймер: если вы мыслите только плагинами для Wordpress, дальше лучше не читать, будет больно.

Установка Google reCaptcha V3: получение ключей

Сначала нам надо зайти на сайт Google reCaptcha и авторизоваться в панели администрирования. Вам нужно иметь свой аккаунт от Google почты.

консоль goolge recaptcha

Потом, в панели администрирования, нужно нажать “плюс”. У вас откроется страница, в которой надо будет заполнить пару полей.

добавление новой recaptcha к сайтуЗдесь все просто: Ярлык - любое название, Тип reCaptcha - выбираете V3, Домены - указывайте свой сайт без протокола, можно указать еще поддомен к этому сайту, который хотите защитить.

настройка recaptchaПосле нажимаете сохранить, и Вам дадут 2 ключа: ключ сайта и секретный ключ. Ключ сайта мы будет размещать в клиентской части (в браузере через JavaScript), а секретный ключ спрячем от всех на сервере.

получение ключей от recaptcha

Установка ключа сайта Google reCaptcha

Начинаем работу с ключом сайта (не путать с секретным). Как говорит нам Google документация, нам нужно для каждого пользователя генерировать специальный (уникальный) токен и отправлять себе на сервер с помощью JavaScript. За генерацию отвечает готовая функция написанная самим Google.

Важно: нельзя отправлять token напрямую в Google из JavaScript, только с сервера! Поэтому логика такая: получили токен -> отправили к себе на сервер -> отправили с сервера в Google -> полученный ответ обрабатываем и делаем с ним уже что хотим.

Способ 1: подойдет для SPA или PHP-сайта

SPA - это Single Page Application, обычно так называют приложения на Vue.js без роутинга.

Генерируем и отправляем токен из индексного файла (index.html, index.php). Можно добавить данный скрипт в footer или header, если ваш проект разбит на html,php файлы.

Для удобства прикладываю ссылку на Github для кода ниже.

P.S: Код очень объемный, поэтому лучше ознакомиться с ним на GitHub.

пример кода 1

Давайте разбираться, что же я там написал.

Важно: в двух местах вместо “ВАШ_КЛЮЧ” устанавливаем общий ключ сайта, мы его выше получили.

Первый скрипт: мы подключаем библиотеку от Google к сайту. Второй скрипт: функция (почти как из документации), которая будет отправлять token к нам на сервер. Как видите, переменная json содержит в себе token в формате JSON. А переменная xhr создает новый запрос через XMLHttpRequest.

Полученный (сгенерированный) toket мы отправялем в файл recaptcha.php (мы его через минуту напишем), который находится по адресу site.ru/functions/recaptcha.php.

Способ 2: подходит для компонентного подхода во Vue.js

Пользуетесь Gulp или Webpack? Вообще не проблема, этот способ для вас.

Для отправки запроса (с токеном) я буду использовать библиотеку axios. Можете использовать XMLHttpRequest. Но лучше axios, инструкция написана под него.

Установить axios в свой проект можно с помощью команды:

npm install axios

Если у вас Mac или Linux добавьте перед npm команду sudo. А после добавьте axios в проект.

const axios = require('axios');

Ниже представлю код для Google reCaptcha. Данный код нужно добавить в mounted! Не нужно добавлять в created, только в mounted. Потому что таков функционал Vue.js, и только в mounted у нас монтируется виртуальное dom-дерево (html), к которому можно обращаться.

Для удобства прикладываю ссылку на Github для кода ниже.

P.S: Код очень объемный, поэтому лучше ознакомиться с ним на GitHub.

пример кода 2

Не пугайтесь большого кода, тут все просто. Сейчас я все объясню.

Я создал переменную reCaptcha, в которую записываю promise (обещание). Resolve - это значит все прошло успешно, reject (или error) - какая-то ошибка.

С помощью переменной $script я создаю <script> в который добавляю ссылку на API Google. Заместо “ВАШ_КЛЮЧ” вставьте свой ключ сайта полученный в Google (мы его выше получили при регистрации сайта). Далее в resolve() я записываю метод, который вставит наш скрипт в конец <head>. А чуть ниже я ставлю таймер на 3 секунды, вдруг ничего не произойдет, и у нас появится ошибка (reject).

Ниже я активирую промис и создаю цепочку из then и error. Result выполнится только в случае выполнения resolve().

В result происходит следующее: мы ставим обязательный таймер в 1 секунду (может хватит и 500 мс), это нужно для того, чтобы axios смог дождаться генерации токена за которую отвечает функция Google. Тут вместо “ВАШ_КЛЮЧ” тоже нужно установить свой ключ сайта. Не беспокойтесь, эта одна секунда начинает считываться уже во время установки виртуального dom-дерева в физическое (в html документ), даже не заметите этой “паузы”.

Полученный (сгенерированный) toket мы отправялем в файл recaptcha.php (мы его сейчас напишем), который находится по адресу site.ru/functions/recaptcha.php. Catch служит внутренним обработчиком ошибок в axios, можете это не использовать.

Error выполнится только в случае выполнения reject (где я создал в самом начале промиса таймер на 3 секунды), но в случае удачного выполнения resolve этого никогда не произойдет, и reject будет забыт.

Важно: можете отказаться от промиса, главное дайте какое-то время axios, чтобы он начал посылать запрос к вам на сервер, после того, как Google сгенерировал token. Сам промис можно полностью заменить на ассинхронную функцию. Почему я сам так не сделал? Честно, я об этом подумал уже после того как статью написал и скриншоты наделал.

Установка секретного ключа Google reCaptcha

Сейчас мы будем работать с сервером, пример кода покажу на PHP. И да, без этого никак, секретный ключ вы обязательно должны обрабатывать на сервере (можете это делать с помощью Python или Node.js).

Для удобства прикладываю ссылку на Github для кода ниже.

Пример кода:

пример кода получаем ключ от google и обрабатываем на php

Здесь все еще проще. Сначала я исключаю возможность сделать GET запрос на мой скрипт (это мои загоны, можете отказаться от этого). После я стартую сессию. Сессия и все ее переменные будут жить, пока открыт сайт. Полученные данные из POST запроса я обрабатываю через php input (загон vue.js) и записываю в глобальную переменную SESSION полученный token.

Теперь с этим можно уже работать на сервере. Этот токен надо отправить в Google.

Далее весь код (хоть он и рабочий) идет не более как наглядный пример, все-таки это статья для программистов. Ибо вся моя логика может отличаться от логики вашего приложения. Например, вы хотите защитить от спама и атак форму обратной связи. А может быть поле авторизации в личный кабинет. Поэтому, просто ради наглядности давайте отправимся в (абстрактный) скрипт mail.php, который отвечает за рассылку сообщений клиенту.

Для удобства прикладываю ссылку на Github для кода ниже.

Здесь мы напишем следующий код:

отправляем в google ключ на проверку

Google от нас ожидает данных в определенном формате. Поэтому я создаю переменную $secret, в которую записываю секретный ключ (вы сюда свой вставьте). Далее я создаю массив $params, в который записываю секретный ключ и глобальную переменную SESSION, мы создали ее выше (в recaptcha.php) и записали туда token сгенерированный Google.

Далее через метод curl (это как XMLHttpRequest только для PHP) мы отправляем все это дело в Google. Полученный ответ записываем в переменную $response и закрываем соединение. Превращаем $response в JSON с помощью метода json_encode. Переменная будет содержать в себе "success": true или "success": false.

Если интересно какие данные еще приходят от Google читайте документацию или воспользуйтесь die(var_dump($response)), главное обработайте такую логику через axios самостоятельно и в браузер выведете себе содержимое переменной. Просто var_dump() - это как console.log(), только для PHP.

Что делать дальше…

Я надеюсь, что до этого вопроса не дойдет, но, если он остался в голове, давайте я натолкну вас на мысль таким скриптом (снова на PHP):

if ($response['success'] == true) {
   // Здесь происходит отправка сообщения на почту клиента
} else {
       echo json_encode('Опа, ты не прошел reCaptcha');
}

Если результат пришедший от Google, и который мы сохранили в переменную $response в условном файле mail.php равен true, то можно выполнять отправку сообщения клиенту. Если нет - тут какая-то логика обработки ошибок.

Внимание

И еще, если вы попытаетесь отправить на сервера Google токен, который уже был задействован (т.е вы его сгенерировали всего лишь один раз) - получите отказ в прохождении капчи. Поэтому, доработайте свое приложение так, чтобы после каждого нажатия на submit у формы, генерировался новый токен и отправлялся к вам на сервер. Ну а дальше, новый токен проверяется у Google. 

Спасибо за внимание. Надеюсь, статья была для вас полезна.

Опубликовано: 2020-03-25 18:29