Adding recaptcha to contact form to thwart bot spam
by mark | 27 Jul 2022, 5:05 p.m.
I have been inundated with spam through my contact form recently. Mostly benign offers of web design and so on. But I still don't want them. So I elected to install a reCAPTCHA service so they have to convince Google they're human before sending me a mail I just instantly delete.
This was quite straightforward in the end.
Install a package
Some kind soul has already done the work in setting up a Django form field which talks to Google for you. So all you need to do is pipenv install django-recaptcha
. I'd also update the lock and requirements files; pipenv lock && pipenv lock -r > requirements.txt
. Make sure to enable the package in config.py by installing its app. It is called captcha
.
Generate secrets
You can use the Google recaptcha admin console to register your domain with Google and also generate a public / private key pair. I'd add 127.0.0.1 to the domain list so you can test it locally a well. The secrets are to be called RECAPTCHA_PRIVATE_KEY
and RECAPTCHA_PUBLIC_KEY
.
Add to form
You need to add the Recaptcha box to your form. This is very easy. First, in forms.py, load the objects:
from captcha.fields import ReCaptchaField from captcha.widgets import ReCaptchaV2Checkbox
And then add this as a field. I have a ModelForm that drives the Contact app, so this was adding one line after I declared it:
class ContactForm(ModelForm): captcha = ReCaptchaField(widget=ReCaptchaV2Checkbox)
I also use Crispy Forms, so I just added captcha as a Field to its Layout object.
Add invalid handling
Now the package does all the Google talking for you and the validate function will fail if Google thinks you are a robot. This is when you have to do the image clicking stuff. I wanted to communicate this to the user in case they are acting like a robot. So I added an invalid form handler to the view that my form posts to:
def form_invalid(self,form): messages.add_message(self.request, messages.ERROR, form.errors) return super().form_invalid(form)
That was it. Already seen in the logs someone try to post me a comment and it not show up (as the form was invalid so the instance wasn't saved). I'm sure some guys will still spam me stuff out of spite but you cannot have everything.
Back to all articles