How to add reCAPTCHA to your django forms

We use recaptcha to protect against bots. I will show you how to integrate Google’s reCAPTCHA with your django forms.

Here are the steps to make it work:

  1. Obtain a public and a private key.
  2. Download a plugin for python.
  3. Render the widget in the form page.
  4. Verify the answer by sending a request to google’s server.
  5. Check the response.

Obtaining keys

You need a google account to get the keys. Then go to https://www.google.com/recaptcha/admin/create, where you will be prompted to enter a domain, such as recaptcha.net, example.com, etc. Fortunately, it accepts “localhost” as a valid domain so local development is possible. Note that you need to make it global so check that option.

Once you have your keys, put it in your settings.py.

# settings.py
RECAPTCHA_PUBLIC_KEY = 'some-key'
RECAPTCHA_PRIVATE_KEY = 'some-key'

Downloading plugin

Next you need to download a python plugin. Here is the page of recaptcha-client. Since it is available via pypi, you can do a ‘pip install recaptcha-client’. Once set, you can now start rendering the widget.

Rendering the widget

The modules that you need from the plugin reside in recaptcha.client.captcha. It contains a method called displayhtml() that returns a string of javascript code which you use to render the widget. Here is a sample usage:

# views.py
def display_form(request):
    form = SomeForm()
    # assuming your keys are in settings.py
    public_key = settings.RECAPTCHA_PUBLIC_KEY
    script = displayhtml(public_key=public_key)
    return render_to_response('form.html', {'form':form,'script':script}, context_instance=RequestContext(request))
)

In your form.html

# form.html
    <form>
        {{ form }}{% csrf_token %}
        {{ script }}
    </form>

which will yield something like this, in html:

    <form>
        <!-- form elements here -->
        <script type="text/javascript" src="http://api.recaptcha.net/challenge?k=6LdSucISAAAAADc_huFvVv0fCCEfcVJNvbqeY-TN"></script>
    </form>

By now, you should be seeing a widget that displays the prompt.

Verifying answer

Upon form submission, you need to verify the user’s answer by POSTing to http://www.google.com/recaptcha/api/verify. There is another method in recaptcha.client.captcha called submit() that takes four arguments and does the POSTing for you.

Below is a helper method I wrote which shows how to obtain the required arguments that you need to submit.

# views.py
    ...
    if request.method == 'POST':
        check_captcha(request)

def check_captcha(request):
    remote_ip = request.META['REMOTE_ADDR']
    challenge = request.POST['recaptcha_challenge_field']
    response = request.POST['recaptcha_response_field']
    private_key = settings.RECAPTCHA_PRIVATE_KEY
    return submit(challenge, response, private_key, remote_ip)

Final Step: Checking the response

The method above will return an instance of RecaptchaResponse, with attributes is_valid and error_code that you can use to determine if the answer is indeed correct.

Continuing from our example:

# views.py
    ...
    if request.method == 'POST':
        result = check_captcha(request)
        if result.is_valid:
            # process your form now
        else:
            # you can display the error code here or just return the form
            # to your form page, to prompt for another

And you’re done. 🙂