Использование reCAPTCHA в Google App Engine
Борьба со спамом приобретает промышленные масштабы, и одним из способов помешать искусственному интеллекту присылать нашему приложению «рекламные подарки», является установка на сайт CAPTCHA.
Одним из популярных разновидностей такого сервиса является reCAPTCHA, созданная в университете Карнеги Меллон, которая не только дает наилучшие результаты из себе подобных, но и помогает человечеству оцифровывать книги.
С чего начать?
Сначала необходимо получить ключ сервиса на сайте recaptcha.net.
После регистрации вы сможете создать неограниченное количество сервисных ключей для вашего домена.
Примечание: Если вы хотите, чтобы reCAPTCHA корректно работала в отладочной среде, то необходимо также получить ключ для localhost.
После генерации пары ключей, вы увидите следующую страницу:
Сохраните этот публичный и приватный ключ – они понадобятся вам позже. Если вдруг они будут случайно потеряны, то сможете вернуться на сайт recaptcha.net и снова их получить. Ни в коем случае не сообщайте свой приватный ключ.
После регистрации в сервисе, вам потребуется простой класс на языке 
Python, адаптированный для App Engine. Скачать его можно здесь. После загрузки переименуйте его в captcha.py и скопируйте в каталог приложения (я предпочитаю размещать его в подкаталоге recaptcha/client/ – не забудьте добавить к каждому подкаталогу пустой файл __init__.py).
Для демонстрации работы мы дополним стандартный пример из Руководства для начинающих Google App Engine.
Откройте файл helloworld.py и добавьте строчки импорта модулей captcha и environ:
from os import environ from recaptcha.client import captcha
Затем перейдите к контроллеру MainPage и добавьте следующее:
chtml = captcha.displayhtml( public_key = "ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ", use_ssl = False, error = None) template_values = { ... 'captchahtml': chtml }
Соответственно замените выражение ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ своим ключом, иначе получите ошибку:
«Invalid public key. Make sure you copy and pasted it correctly.»
Теперь перейдите к файлу с шаблоном и добавьте тэг captchahtml внутри формы:
<form>
...
{{ captchahtml }}
</form>
После этого можно открыть свой браузер и увидеть reCAPTCHA в отдельном iframe:
Теперь после того, как получены отправленные через форму данные, нам необходимо выполнить проверку того, что в катпчу введен правильный код. Мы проведем изменение метода post класса Guestbook и добавим код:
def post(self): challenge = self.request.get('recaptcha_challenge_field') response = self.request.get('recaptcha_response_field') remoteip = environ['REMOTE_ADDR'] cResponse = captcha.submit( challenge, response, "ВАШ-ПРИВАТНЫЙ-КЛЮЧ", remoteip) if cResponse.is_valid: # код введен верный # продолжаем работу приложения else: error = cResponse.error_code ...
Аналогично, замените выражение ВАШ-ПРИВАТНЫЙ-КЛЮЧ ранее полученным приватным ключом.
Информация, введенная пользователем в поле reCAPTCHA будет отправлена на проверку вместе с его IP адресом. Мы получим ответ от сервера reCAPTCHA в формате объекта RecaptchaResponse.
Объект RecaptchaResponse имеет два атрибута:
- is_valid, установленный в True, если тест был пройден удачно (в противном случае False)
- error_code , содержащий код ошибки API, если произошла какая-то проблема.
Примечание: В Руководстве для начинающих Google App Engine, информация введенная в формы, передавалась контроллеру Guestbook. В обычном случае мы будем передавать ее в контроллер MainPage, и обрабатывать код ошибки из объекта RecaptchaResponse (если он будет) методом displayhtml класса captcha:
chtml = captcha.displayhtml( public_key = "ВАШ-ПУБЛИЧНЫЙ-КЛЮЧ", use_ssl = False, error = cResponse.error_code)
Это позволит вывести читаемое сообщение об ошибке пользователю:
и дать ему возможность еще раз ввести ответ на CAPTCHA без необходимости повторного ввода других данных в поля формы.
Имейте ввиду: Для каждой отправленной пользователем CAPTCHA, выполняется удаленный запрос к серверу reCAPTCHA. Этот запрос является синхронным, и таким образом посетитель будет ждать некоторое время, пока сервер обработает этот запрос. В том случае, если сервер reCAPTCHA в этот момент не был доступен, будет возвращен код ответа recaptcha-not-reachable.