Evgenii Legotckoi
23 сентября 2017 г. 17:55

Django - Урок 027. Добавление Google reCAPTCHA

Добавил на сайт reCAPTCHA при регистрации пользователей и некоторых других действиях анонимных пользователей, а то слишком много роботов регистрируется на сайте.

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

Для внедрения reCAPCTHA на сайт необходимо зарегистрировать свой сайт в админке reCAPTCHA .

В качестве домена я выбрал IP адрес локальной петли своего ПК, на котором веду разработку сайта.


Внедрение

Внедрение reCAPTCHA состоит из двух шагов:

  1. Внедрение reCAPTCHA на клиентской стороне, то есть в HTML коде
  2. Внедрение reCAPTCHA на серверной стороне

При регистрации сайта будет сгенерировано два ключа:

  1. Site key - Ключ, который будет помещаться на HTML странице
  2. Secret key - Ключ, который бует использоваться для коммуникации сайта и сервисом Google reCAPTCHA

Процесс внедрения будет следующий. На HTML странице в форме, которая требует валидации действий пользователя, помещаем script reCAPTCHA, и ключ сайта.

На стороне сервера внедряем декотор для view функции или класса view, если Вы используете Class Based View в сайте на Django. Я использую Class Based View.

При заполнении формы и отправки её данных на сервер, необходимо выдернуть из запроса информацию об ответе о валидации каптчи, а потом отправить запрос на сервер Google для верификации сайта и получения окончательного результата валидации. Ответ с первоначальным результатом валидации каптчи будет содержаться в поле g-recaptcha-response. Именно этот ответ и отправляется с секретным ключом на сервера Google для верификации сайта и получения окончательного результата верификации пользователя.

Для создания запроса воспользуемся библиотекой requests .

  1. pip install requests

Декоратор

Secret Key помещаем в настройки вашего сайта, самый простой вариант - это добавить его в settings.py , хотя и не самый безопасный.

  1. GOOGLE_RECAPTCHA_SECRET_KEY = '6LdqzjEUAAAAAKTDYsfuwZce-oa214GC8QeChVBF'

Далее создаем файл decorators.py , в котором будет содержаться декоратор reCAPTCHA. Помещаем этот файл рядом с файлам views.py , models.py и т.д.

  1. from django.conf import settings
  2. from django.contrib import messages
  3.  
  4. import requests
  5.  
  6.  
  7. def check_recaptcha(function):
  8. def wrap(request, *args, **kwargs):
  9. request.recaptcha_is_valid = None
  10. if request.method == 'POST':
  11. recaptcha_response = request.POST.get('g-recaptcha-response')
  12. data = {
  13. 'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
  14. 'response': recaptcha_response
  15. }
  16. r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
  17. result = r.json()
  18. if result['success']:
  19. request.recaptcha_is_valid = True
  20. else:
  21. request.recaptcha_is_valid = False
  22. messages.error(request, 'Invalid reCAPTCHA. Please try again.')
  23. return function(request, *args, **kwargs)
  24.  
  25. wrap.__doc__ = function.__doc__
  26. wrap.__name__ = function.__name__
  27. return wrap

Далле оборачиваем декоратором необходимую вьюшку:

  1. # -*- coding: utf-8 -*-
  2.  
  3. from django.conf.urls import url
  4.  
  5. from . import views
  6. from .decorators import check_recaptcha
  7.  
  8. app_name = 'registration'
  9. urlpatterns = [
  10. url(r'^register/$', check_recaptcha(views.RegisterView.as_view()), name='register'),
  11. ]

А в самой вьюшке делаем проверку на валидность reCAPTCHA. В моём случае эта была вьюшка, наследованная от FormView класса.

  1. class RegisterView(FormView):
  2. form_class = UserCreationForm
  3. template_name = 'register.html'
  4.  
  5. def form_valid(self, form):
  6. # проверка валидности reCAPTCHA
  7. if self.request.recaptcha_is_valid:
  8. form.save()
  9. return render(self.request, 'register_success.html', self.get_context_data())
  10. return render(self.request, 'register.html', self.get_context_data())

Клиентская сторона

На клиентской стороне необходимо добавить код подключения скрипта, место расположения каптчи, а также вывод сообщений об ошибках.

  1. {% extends 'base.html' %}
  2. {% block content %}
  3. <form action="{% url 'register' %}" method="post">
  4. {% csrf_token %}
  5. {{ form.as_p }}
  6. <script src='https://www.google.com/recaptcha/api.js'></script>
  7. <div class="form-group g-recaptcha" data-sitekey="6LdqzjEUAAAAABRAtK1a3QhIWbn46X_gdcXvhnbG"></div>
  8. {% if messages %}
  9. {% for message in messages %}
  10. {{ message }}
  11. {% endfor %}
  12. {% endif %}
  13. <input type="submit" value="Зарегистрироваться">
  14. </form>
  15. {% endblock %}

Результат

В итоге получаем достаточно простое внедрение reCAPTCHA на Django сайте.

Для Django рекомендую VDS-сервера хостера Timeweb .

Вам это нравится? Поделитесь в социальных сетях!

SB
  • 29 апреля 2019 г. 12:46

Thank you! Really an elegant and fast solution!
You saved my day, thank again :-)

Sergio

Evgenii Legotckoi
  • 29 апреля 2019 г. 13:50

Thank you for feed back. If you will have more questions, you can ask on the forum

V
  • 4 июля 2020 г. 14:34

Спасибо.

Только использую декоратор не в urls.py а перед views

t
  • 15 февраля 2021 г. 14:23

Добрый день, а эти же действия не подходят для reCHAPTCHA v3?

Evgenii Legotckoi
  • 2 июля 2021 г. 17:25

Специально не проверял поддержку для версии 3

t
  • 2 июля 2021 г. 18:20

Как проверю напишу:)

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь