Evgenii Legotckoi
Evgenii LegotckoiSept. 23, 2017, 7:55 a.m.

Django - Tutorial 027. Implementation Google reCAPTCHA

I added to the site reCAPTCHA when registering users and some other actions of anonymous users, and then too many robots are registered on the site.

The adding of reCAPTCHA was done through the decorator function, so that it was possible to reuse this method for site views.

To implement reCAPCTHA on the site, you need to register your site in the reCAPTCHA admin area.

As a domain, I chose the IP address of the local loop on my PC where I am developing the site.


Implementation

The implementation of reCAPTCHA consists of two steps:

  1. The implementation of reCAPTCHA on the client side, that is, in HTML code
  2. The implementation reCAPTCHA on the server side

When registering the site, two keys will be generated:

  1. Site key - The key that will be placed on the HTML page
  2. Secret key - The key that will be used to communicate the site and the Google reCAPTCHA service

The implementation process will be as follows. On an HTML page in a form that requires validation of user actions, place the script reCAPTCHA, and the site key.

On the server side, we embed the decoder for the view function or the view class, if you use the Class Based View in the Django site. I'm using the Class Based View.

When filling out the form and sending its data to the server, it is necessary to pull out information about the response to the validation of the captcha, and then send a request to the Google server to verify the site and get the final result of validation. The answer with the initial result of the validation of the captcha will be contained in the g-recaptcha-response field. It is this answer that is sent with a secret key to the Google server to verify the site and get the final result of user verification.

To create a query, use the requests library.

pip install requests

Decorator

Secret Key is placed in the settings of your site, the simplest option is to add it to settings.py , although not the safest.

GOOGLE_RECAPTCHA_SECRET_KEY = '6LdqzjEUAAAAAKTDYsfuwZce-oa214GC8QeChVBF'

Next, create a file decorators.py , which will contain the decorator reCAPTCHA. We put this file next to the files views.py, models.py, etc.

from django.conf import settings
from django.contrib import messages

import requests


def check_recaptcha(function):
    def wrap(request, *args, **kwargs):
        request.recaptcha_is_valid = None
        if request.method == 'POST':
            recaptcha_response = request.POST.get('g-recaptcha-response')
            data = {
                'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
                'response': recaptcha_response
            }
            r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
            result = r.json()
            if result['success']:
                request.recaptcha_is_valid = True
            else:
                request.recaptcha_is_valid = False
                messages.error(request, 'Invalid reCAPTCHA. Please try again.')
        return function(request, *args, **kwargs)

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap

Then we wrap the decorator with the required view:

# -*- coding: utf-8 -*-

from django.conf.urls import url

from . import views
from .decorators import check_recaptcha

app_name = 'registration'
urlpatterns = [
    url(r'^register/$', check_recaptcha(views.RegisterView.as_view()), name='register'),
]

And in the view itself we do a validation for the validity of reCAPTCHA. In my case, this was a view inherited from the FormView class.

class RegisterView(FormView):
    form_class = UserCreationForm
    template_name = 'register.html'

    def form_valid(self, form):
        # проверка валидности reCAPTCHA
        if self.request.recaptcha_is_valid:
            form.save()
            return render(self.request, 'register_success.html', self.get_context_data())
        return render(self.request, 'register.html', self.get_context_data())

Client side

On the client side, you need to add the script's connection code, the location of the captcha, and output error messages.

{% extends 'base.html' %}
{% block content %}
    <form action="{% url 'register' %}" method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <script src='https://www.google.com/recaptcha/api.js'></script>
        <div class="form-group g-recaptcha" data-sitekey="6LdqzjEUAAAAABRAtK1a3QhIWbn46X_gdcXvhnbG"></div>
        {% if messages %}
            {% for message in messages %}
                {{ message }}
            {% endfor %}
        {% endif %}
        <input type="submit" value="Register">
    </form>
{% endblock %}

Conclusion

As a result, we get a fairly simple introduction of reCAPTCHA on the Django site.

For Django I recommend VDS-server of Timeweb hoster .

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

SB
  • April 29, 2019, 2:46 a.m.

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

Sergio

Evgenii Legotckoi
  • April 29, 2019, 3:50 a.m.

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

V
  • July 4, 2020, 4:34 a.m.

Спасибо.

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

t
  • Feb. 15, 2021, 3:23 a.m.

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

Evgenii Legotckoi
  • July 2, 2021, 7:25 a.m.

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

t
  • July 2, 2021, 8:20 a.m.

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

Comments

Only authorized users can post comments.
Please, Log in or Sign up
e
  • ehot
  • April 1, 2024, 12:29 a.m.

C++ - Тест 003. Условия и циклы

  • Result:78points,
  • Rating points2
B

C++ - Test 002. Constants

  • Result:16points,
  • Rating points-10
B

C++ - Test 001. The first program and data types

  • Result:46points,
  • Rating points-6
Last comments
k
kmssrFeb. 9, 2024, 5:43 a.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVADec. 25, 2023, 9:30 p.m.
Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJoDec. 25, 2023, 7:38 p.m.
Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
GvozdikDec. 19, 2023, 8:01 a.m.
Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Now discuss on the forum
a
a_vlasovApril 14, 2024, 4:41 p.m.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел ДорофеевApril 14, 2024, 12:35 p.m.
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrexApril 4, 2024, 2:47 p.m.
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
AC
Alexandru CodreanuJan. 19, 2024, 10:57 p.m.
QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…

Follow us in social networks