meta-data
Это моя первая статья, так что просьба сильно яро не минусовать, а то расстроюсь и вообще ничего рассказывать не буду. Это не шутка. Спасибо за сочувствие, начнём понемногу.
Да ладно, шучу я
Данная статья сделана вовсе не для кармы, а для помощи людям, которые столкнулись с теми же проблемами, с которыми когда-то столкнулся и я. А потому, читатели должны чётко понимать, с материалом какого уровня они здесь имеют дело. И если этот текст не достаточно хорош или, тем более, вреден, беспощадно минусуйте, просто желательно при этом обосновывать, что именно не так и как нужно было сделать на самом деле
И так, поехали!
Яндекс капча: попытки установки для самых джун’ых.
Для чего?
Почему вдруг «молодо-зелено» учит «плавали-знаем» тому, что и так описано в оф.документации? Дело в том,что эта документация не сильно newbie‑friendly. И если вы никогда до этого не ставили на сайт капчу, то имеется ненулевой шанс, что и не поставите, не прочитав данное «крео». Документация написана довольно сносно, но не для тех, кто здесь впервые. Не хватает основы — концепции (хотя раздел концепций в документации имеется…).
Возможно, кому-то покажется, что данный материал просто пересказывает официальные инструкции своими словами, но это не так. Дока безжалостна к новичкам, которые просто не понимают, что скрывается за «умными» словами. Я же здесь попытался устранить это досадное упущение.
Статья поможет избавить любопытный ум от множества пугающих вопросов, которые невозбранно поселяются в утомлённой голове при попытке понять процесс, который издалека кажется таким простым, но вскоре выясняется, что он таковым лишь притворяется.
Здесь нет примеров кода, но он вам и не понадобится: понимая концепцию работы и прочитав документации, вы сможете самостоятельно накодить нужное решение для своей конкретной ситуации.
И так, начнём.
Пара слов о тех самых «квадратиках с гидрантами»
Придётся поговорить о том, что такое капча. Нет я серьёзно! Ещё несколько лет назад этот абзац никто не стал бы читать, так как все испытывали фрустрацию от непонимания нужно ли тыкать квадратик, на который едва попало два пикселя гидранта или он тут лишний. Но сегодня мир защиты сайтов представлен широким ассортиментом капчений под любой нескромный повод и диаметр проблемы. И размытые картинки, и едва читаемый текст, и ползунки, и чёртовы светофоры с гидрантами, и даже простой чек-бокс с вопросом «Ты не робот? Ты уверен?» — всё это инструменты для одной простой задачи – не пустить на сайт ботов (ну и нашему умишке поразмяться)).
Ну и расшифруем сам акроним CAPTCHA для полноты картины - Completely Automated Public Turing test to tell Computers and Humans Apart. Всё, можно смело забывать…
Ты не видишь кабана… (ну, как в том фильме)
Иногда, зайдя на сайт и пугливо оглядевшись вокруг, ты вдруг с облегчением вздыхаешь: «Тут нет капчи». Но в этот момент она смотрит на тебя в упор… Ощупывает тебя невидимой клешнёй и алчет протестировать гидрантами. Такова и Yandex SmartCaptcha.
Ты не видишь её, но она видит тебя насквозь… Прячется за зарослями фоток, смотрит на тебя, как на вредоносный код, и пытается понять, чисты ли твои помыслы есть ли у тебя душа. И если ты ей чем-то не угодишь, будешь решать её загадки, как миленький.
Что ж, попробуем разобраться как посадить этого милого цербера на цепь и на своём сайте.
Нужны Yandex’у деньги - се ля ви
Чтобы с головой окунуться в мир капченья, придётся сначала лицом к лицу столкнуться с жабой рыночными отношениями. В какой-то момент, Яндекс невзначай предложит перейти на новый уровень отношений и привязать к аккаунту карту. Да-да, ту самую, с деньгами секретным кодом. Но, на самом деле, это - всё. Платить ни за что не придётся. В месяц можно сделать 250 000 проверок бесплатно. Что для подавляющего числа сервисов, наверно, за горизонтом мечтаний. Те же, у кого получится набрать столько заявок в месяц, деньги на капчу считать, наверно, не станут.
И так, с теми отчаянными смельчаками, у кого есть платёжный аккаунт яндекса, мы продолжаем. А для того, кто понимает, что тут вопрос не только в деньгах, есть альтернатива.
Набор ключей
Перед началом, нужно вытряхнуть из яндекса пару увесистых инструментов: ключ сервера и ключ клиента.
Какие же двери открываются этими ключами? Первая дверь впускает на сайт скрипт для работы яндекс капчи. Через вторую дверь уходит запрос на проверку пользователя. Но между этими дверями нужно преодолеть долгий путь по мрачным коридорам настройки яндекс капчи. Приглашаю пройтись по этому пугающему месту вместе. Берите кресты и канделябры – мы начинаем…
7 шагов в бездну
Чтобы поставить SmartCaptcha на сайт, нужно пройти 7 кругов ада шагов ада…:
1. Прибить скрипт загрузки куда-нибудь в код сайта:
<script src="https://smartcaptcha.yandexcloud.net/captcha.js?render=onload&onload=onloadFunction" defer></script>
Теперь капчё сможет загрузить себя на сайт, чтобы грудью прикрыть форму отправки от ничтожных ботов.
Нет-нет, бубен откладывать пока рано, он нам ещё пригодится
2. Далее нужно отвести специальное место под капченье. Я не шучу! Надо указать капче её место, чтобы знала, кто тут босс:
<div id="captcha-container" style="height: 100px" ></div>
3. Теперь нужно навертеть на форму проверку яндекс-капча (далее буду ласково звать этого зверя «япча», чтобы как у индейцев отражало суть):
Привожу полный код из документации, чтобы было понятно, как это работает «в пробирке»:
<form id="form">
<div id="captcha-container"></div>
<input type="submit" onsubmit="handleSubmit()" />
</form>
<script>
const form = document.getElementById('form');
function onloadFunction() {
if (!window.smartCaptcha) {
return;
}
window.smartCaptcha.render('captcha-container', {
sitekey: '<ключ_клиентской_части>',
invisible: true, // Сделать капчу невидимой
callback: callback,
});
}
function callback(token) {
form.submit();
}
function handleSubmit(event) {
event.preventDefault();
if (!window.smartCaptcha) {
return;
}
window.smartCaptcha.execute();
}
</script>
На этом этапе может показаться, что всё выполнено как надо и можно идти квасить чай, но сильно наквашиваться рано, потому что япча тебя только обнюхала и даже не распахнула свою пасть
4. Разжиться токеном
Что такое токен? Зашифрованное досье, хэш вселенной? По-сути, токен — это набор символов, по которым различают одну сущность от другой. Такой себе отпечаток пальца посетителя сайта.
Токен получается во время выполнения функции callback, указанной выше. Так же он прилетает в контейнер капчи, созданный на втором шаге и сохраняется в значении инпута.
Куда с этим токеном идти? Благо япча сильно далеко не шлёт, только на сам сервис проверки посетителя Yandex SmartCaptcha, чем мы дальше и попробуем поразвлекаться.
Но, прежде чем переходить к следующему шагу, думаю, стоит убедится, что на данном этапе всё понятно и информация не вызывает отторжения, а потому немного повторим всё что произошло до этого этапа, другими словами.
Код из доки пунктом выше выглядит дружелюбным и понятным, но это не так – япча водит тебя за нос. Внимательно следите за яйцами (цены то вверх, то вниз). По пунктам:
1) подключили скрипт, где указали, какая функция будет запускаться при загрузке скрипта
<script src="https://smartcaptcha...&onload=onloadFunction"
2) внутри этой самой onloadFunction указали, какая функция будет запускаться при вызове метода smartCaptcha.execute():
window.smartCaptcha.render('captcha-container', {
callback: callback...
3) функция callback вызывается в обработчике формы:
function handleSubmit(event) {
smartCaptcha.execute()...
4) callback получает от капчи тот самый долгожданный токен, будь он трижды выглажен и выбит:
function callback(token) {…}
Всё вроде понятно, да?. Но! Что если таких форм не одна, а много разных, а обработчик у всех один? Что если нужен отдельный компонент vue/react, который стоит отдельно от формы? Много вопросов. А что, если вообще в 1 кг не 1024 грамма, а всего 1000… - вопрос из той же серии.
Дальше держим бубен крепче
Наверно нет необходимости пихать контейнер для капчи в каждую отдельную форму на сайте. Можно было бы, наверно, обойтись установкой капчи в одном месте, а обработчики формы вызывать из других частей проекта. И всё было бы просто, но метод smartCaptcha.execute не асинхронный и ничего не возвращает. То есть, если запустить проверку капчей в обработчике форм, а сам callback хранить в отдельном компоненте, который просто добавляется в проект и ничего о форме толком и не слышал, то результата мы просто не дождёмся. Придётся размазывать по проекту инжекты, которые будут гонять команды между формой и компонентом. И отлавливать момент получения токена в callback. Всё это, разумеется, решаемо, но какого-то одного концептуального решения тут не найти и каждый раз, возвращаясь к задаче, невзначай находишь какой-то более лучший подход чем в предыдущем варианте, а потому до конца никогда не можешь быть уверен, решил ли ты вопрос или просто ещё мало над ним думал.
Так же нужно держать в уме прискорбный факт - токен получается только один раз для одного контейнера. То есть при повторной отправке той же формы токен в callback уже не упадёт. Благо, он сохраняется после получения в отрисованном контейнере (<div id="captcha-container” ></div>) и добывается при помощи вызова метода smartCaptcha.getResponse().
Немаловажно понимать ещё и то, что именно на этом этапе япча пристально досматривает посетителя и принимает ответственное решение, развлечь ли его капче-загадкой аль мал ещё, пусть отдыхает. И вот тут, устав от тягот всей этой возни с настройкой, вдруг может осенить чиловая мысля, что вот этот торжественный показ капчи и есть та самая благоговейная проверка на человечность и дальше ничего делать не нужно. Типа, если смог пройти испытание япчёй, значит точно человюга, а потому достоин, а потому давай сюда свою заявку поскорее. Но, к счастью япчи, этого мало. Дело в том, что если вбить в поиск «яндекс капча», то не так много результатов будут связано именно с настройкой капчи, бОльшая часть будет обсуждать способы её обхода. Дальше, как говорится, пусть бессознательное само сделает вывод, хотя тут и так всё понятно – продолжаем каптить япчу.
5) Думаю, до этого момента дошли не все, а только избранные, для кого данный вопрос совсем непраздный. Открою маленький секрет для стойких посвящённых: добрые люди уже разработали кучу компонентов для использования их в SPA’шках. Даже в доке япчи есть ссылка на компонент react. Конечно, это не избавит от всех проблем, которые я описал чуть выше, но если прикрутить его в тупую ко всем формам на странице, то получать заветный токен, наверное, станет не так сложно.
И так, на предыдущем шаге мы получили токен и теперь его нужно аккуратно всунуть в пасть япчи для «порядку». Да-да, это ещё не всё. Нет, не всё…
Чтобы понять кто решил заветный ребус (если ребус был показан), нужно этот токен отправить на сервер Яндекс капчи. Там разберутся кто is who и вынесут вердикт. Для этого не нужно ничего придумывать, документация заботливо даёт нам код бэкенда, который берёт всю эту незатейливую, но ответственную работу на себя.
6) Код для проверки токена - серверный, так как по заветам Yandex SmartCaptcha, необходимо хранить ключ сервера в строжайшей тайне от фронтальной части сайта. Оно, собственно, и понятно: если на твой сайт случайно заглянул владелец автомойки из Воронежа или, допустим, из-под Уагадугу, у которого своих 250 тыщ(!) проверок на этот месяц кончилось, то он может решить, что и твои тебе на шею слишком давят, а значит нужно разгрузить немного твою ношу…
Далее, перед отправкой запроса на проверку созданного для пользователя токена, необходимо пристегнуть к нему этот самый серверный ключ (полученный в самом начале в кабинете яндекса).
Именно вот эта самая отправка токена на проверку и засчитывается яндексом, как единица проверки. То есть не количество раз заходов на сайт, а именно отправка токена. Таких проверок можно сделать 250 000 в месяц.
7) Получаем от серверной части результат проверки и кричим в экстазе от проделанной работы. Если капча признала в запросе человека, отправляем заявку клиенту. Если нет – отправляем бота в banю. Клиент в восторге, бот в запое от депрессии, мы, на радостях, отмечаем событие на втором этаже Макдака. Что может пойти не так?
В приступе дичайшей радости от прохождения проверки вдруг может осветить блаженная мысля: если пользователь не бот, то после проверки можно просто сохранить флаг статуса посетителя, то есть, if status === human, то можно и не делать больше никаких проверок, если посетитель вдруг отправит ещё одну форму. Один раз проверил и пусть дальше шлёт заявки с миром без проверок, а то вдруг он что-то напутал в первой. Разумеется, так делать нельзя и на всякий случай озвучу «с-фига-бы»: боту ничего не мешает просканировать код на фронтенде и с радостью воспользоваться любезно предоставленной возможностью – самому себе поставить статус, а сам он себя ботом точно не считает…
Осталось 2 вопроса
Чё так сложно?
Я не знаю, вопрос к яндексу. Наверно, проще просто невозможно. Думаю, мы все понимаем, что такая серьёзная команда сделала максимум для упрощения работы с инструментом.
И чё, помогает?
Как я уже писал выше, тот же Yandex выдаёт больше инфы по взлому капчи, чем по её настройке. На противоположной стороне баррикад бесчисленная орда: программы по обходу, платные сервисы по взлому и даже плагины для браузера. Раз они есть, стоит думать, что справляются. Думаю, капчеделы от разных сервисов постоянно усовершенствуют свои защиты, но и программы их обхода тоже не стоят на месте. Это как замок на двери: есть те, кто могут его взломать, но это не означает, что замок не эффективен. Какую-то часть капча словит, но 100% гарантии, наверное, не даст.
Саммэри
По итогу нашего нескучного общения должно сложиться полное понимание концепции работы Yandex SmartCaptcha. Это, к сожалению, не оградит вас от необходимости копаться в документации, но заботливо предложит шлем на тех моментах, когда вдруг захочется удариться башкой об стену из-за непонимания того, что происходит на каждом этапе разработки. Теперь вы сможете занырнуть в официальную документацию не боясь, что утонете в огромном количестве задаваемых себе вопросов типа: «А почему так?», «А что, если все не так?», «А что, если я сам бот и просто не осознаю этого?».
Понимая концепцию и заручившись поддержкой документации, вы без труда и затяжных неврозов сможете добавить капчу на свои проекты.
Автор: rommah