Для защиты форм на сайтах от спам-ботов и разного рода автоматических заполнений полей одно из эффективных средств явлется reCaptca. Google имеет в своем арсенале уже третью версию такого сервиса, который упрощает работу человеку и усложняет роботу.
Для наглядности и понимания приведу определение данного сервиса из документации Googl:
«Google reCAPTCHA V3 - это новейший вид капчи от Google, который основан на рейтинге "человечности" пользователя в диапазоне значений от 0.1 до 0.9 и не требует от пользователя выполнения каких-либо заданий.
Подключение такой reCaptca не очень сложно. Давайте рассмотрм один из возможных примеров такого подключения с использованием ajax запросов. Для работы нам понадобятся два ключа: секретный и публичный. Для этого нужно зарегистрировать домен на сайте . Тут же можно посмотреть статистику по запросам, сколько было ложных срабатываний, а сколько раз форма заполнялась человеком. Задаем константы для полученных ключей: CAPTCHA_SITE_KEY = 'публичный ключ' CAPTCHA_SECRET_KEY = 'секретный ключ''
На странице с формой необходимо подключить скрипт, который будет формировать token при отправке публичного ключа на сервер Google и подставлять этот token в нашу форму обратной связи. Далее есть некоторый различия по вызову этих констант в html шаблонах сайта, я приведу небольшие примеры: Для Bitrix, импорт этих констант не должен вызвать проблем, прописав их в init.php, они будут доступны во всем проекте.
<?
define(‘CAPTCHA_SITE_KEY’, ‘публичный ключ’);
define(‘CAPTCHA_SECRET_KEY’, ‘секретный ключ’);
?>
Для Django, эти константы можно прописать в settings.py. Для того, что бы вывести занные в html шаблоне страницы из этого файла, проще всего использовать тэги шаблона simple_tag, который будет выводить данные по имени константы. В файле template_tags.py в папке нашего приложения пропишем такой simple_tag
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def settings_value(name):
return getattr(settings, name, "")
В script видно, как можно применить этот фильтр, не забудьте предварительно загрузить этот файл в html шаблон
Сам скрипт запроса для формирования token может выглядеть примерно следующим образом:
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallbackRecap&render={% settings_value "CAPTCHA_SITE_KEY" %}" async defer></script>
<script>
var onloadCallbackRecap = function() {
grecaptcha.ready(function () {
grecaptcha.execute("{% settings_value "CAPTCHA_SITE_KEY" %}", { action: 'contact_callback' }).then(function (token) {
var recaptchaResponse = document.getElementById('recaptchaResponse');
recaptchaResponse.value = token;
});
});
};
setInterval(() => {
grecaptcha.ready(reCAPTCHA_execute);
}, 120000);
</script>
В первой строке обращаемся к google асинхронно и вешаем callback, в котором формируем token на основании публичного ключа и подставляем значение в поле формы: У данного token есть определенное время жизни, если пользователь откроет страницу с формой и оставит ее на длительное время, то token станет недействительным, однако в форме он у будет указан. Следуем продумать автоматическую смену token во времени. Для этого мы и используем setInterval. На этом с формированием token мы закончили. Мы получили ключи, на основе публичного ключа сделали token и подставили в форму. Так же нам не страшно, если token «протухнет». Далее нужно обработать отправку данных форма по ajax и получить ответ Google, насколько мы «человечны». Начнем с перехвата отправки формы. На отправку формы вешаем событие, которое прерывает это действие. Создаем ajax - запрос.
$("#our_form").on("submit", function(e){
$.ajax({
url: "/ajax_request_form/",
type: "POST",
dataType: "json",
processData : false,
contentType : false,
data: data,
success: function (data) {
}
});
В поле «url» для Bitrix указываем путь до файла « что-то.php». Для Django нужно указать url, по которому будет обрабатываться view.
if(!!$captcha) { // если передан код капчи
$aContext = array(
'http' => array(
'proxy' => 'tcp://10.105.0.217:3128',
'request_fulluri' => true,
),
);
$cxContext = stream_context_create($aContext);
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = RE_SEC_KEY;
$recaptcha_response = $captcha;
// убрали потому как отключили параметры allow_url_fopen = Off и allow_url_include = Off
//$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response, false, $cxContext);
$recaptcha = TTKHelper::getResponseOfCapcha_3($recaptcha_response);
$recaptcha = json_decode($recaptcha);
$_SESSION["test"] = $recaptcha;
if ($recaptcha->score >= 0.5) {
$req["captcha"] = "капча пройдена";
} else {
$req["error"][] = "капча не пройдена";
}
}
pip install request - установим необходимые зависимости python файл url.py
urlpatterns = [
path('feedback /', AboutPage.as_view(), name='about'),
]
файл views.py
from django.http import JsonResponse
from django.conf import settings
from .forms import *
import requests
class AboutPage(View):
""" Обработка формы """
def get(self, request):
feedback_form = FedbackAboutForm()
return render(request, 'page/about.html', {'form': feedback_form})
def post(self, request):
feedback_form = FedbackAboutForm(request.POST)
if feedback_form.is_valid():
#feedback_form.send_email()
#проверка капчи
recaptcha_response = request.POST.get('captcha')
data = {
'secret': settings.CAPTCHA_SECRET_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
recaptcha = r.json()
if recaptcha["score"] > 0.5: // тут будет проверка на «человечность»
response = {
'is_error': False,
}
else:
response = {
'is_error': True,
'error_text': "Рекапча не пройдена",
'error_type': "recaptcha"
}
else:
response = {
'is_error': True,
'error_text': feedback_form.errors,
'error_type': "fields"
}
return JsonResponse(response)
Полезного и практичного использования!