How to validate Google reCAPTCHA v2 in django

Here is a simple example to verify Google reCAPTCHA v2 within Django view using requests library (http://docs.python-requests.org/en/latest/):

import requests
from django.conf import settings

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

def grecaptcha_verify(request):
    if request.method == 'POST':
        response = {}
        data = request.POST
        captcha_rs = data.get('g-recaptcha-response')
        url = "https://www.google.com/recaptcha/api/siteverify"
        params = {
            'secret': settings.RECAPTCHA_SECRET_KEY,
            'response': captcha_rs,
            'remoteip': get_client_ip(request)
        }
        verify_rs = requests.get(url, params=params, verify=True)
        verify_rs = verify_rs.json()
        response["status"] = verify_rs.get("success", False)
        response['message'] = verify_rs.get('error-codes', None) or "Unspecified error."
        return HttpResponse(response)

There is a third-party Django app to implement the new reCAPTCHA v2 here:

https://github.com/ImaginaryLandscape/django-nocaptcha-recaptcha

After installing it, add the following lines to the following files:

# settings.py
NORECAPTCHA_SITE_KEY = <the Google provided site_key>
NORECAPTCHA_SECRET_KEY = <the Google provided secret_key>

INSTALLED_APPS = (
    ....
    'nocaptcha_recaptcha'
)


#forms.py
from nocaptcha_recaptcha.fields import NoReCaptchaField

class YourForm(forms.Form):
    .....
    captcha = NoReCaptchaField()


# In your template, add the following script tag:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

Google has changed the API around, we need to use a POST request now. Here a re-usable solution in case you need to do the validation in more than one django view:

utils.py

# django imports
from django.conf import settings
from django.views.generic.base import View
from django.http import HttpResponseForbidden

# 3rd-party imports
import requests
from ipware import get_client_ip


def is_recaptcha_valid(request):
    """
    Verify if the response for the Google recaptcha is valid.
    """
    return requests.post(
        settings.GOOGLE_VERIFY_RECAPTCHA_URL,
        data={
            'secret': settings.RECAPTCHA_SECRET_KEY,
            'response': request.POST.get('g-recaptcha-response'),
            'remoteip': get_client_ip(request)
        },
        verify=True
    ).json().get("success", False)



def human_required(view_func):
    """
    This decorator is aimed to verify Google recaptcha in the backend side.
    """
    def wrapped(request, *args, **kwargs):
        if is_recaptcha_valid(request):
            return view_func(request, *args, **kwargs)
        else:
            return HttpResponseForbidden()
    return wrapped

then:

views.py

 from utils import human_required

 class MyView(View):

     @human_required
     def post(request, *args, **args):
        pass

Note we are using django-ipware in this solution to get the ip address, but this is up to you. Also, don't forget to add GOOGLE_VERIFY_RECAPTCHA_URL and RECAPTCHA_SECRET_KEY to the django settings file!