Google reCAPTCHA for a Flask app
It is trival to add Google reCAPTCHA to a Flask app. Google's description of reCAPTCHA is "Protect your website from spam and abuse while letting real people pass through with ease."
Credit: based entirely on Vitor Freitas' post
Authored date: 2018 March 08
Technologies: Python 2.7.13, Flask 0.10.1, Jinja2, reCAPTCHA V2
Go to https://www.google.com/recaptcha/admin and register your domain as a reCAPTCHA V2 site. Copy your site and secret keys. In the code examples below I use config variables GOOGLE_RECAPTCHA_SITE_KEY
and GOOGLE_RECAPTCHA_SECRET_KEY
. Adjust your configuration to use your own reCAPTCHA keys.
In your Jinja template add this to your <head>
:
<script src='https://www.google.com/recaptcha/api.js'></script>
And add this to your Jinja template inside your form, e.g. your login or registration form:
<div class="g-recaptcha" data-sitekey="GOOGLE_RECAPTCHA_SITE_KEY"></div>
Create a decorator function that you will use to decorate your view function(s):
import requests
from functools import wraps
from flask import flash, request
from config.settings import GOOGLE_RECAPTCHA_SECRET_KEY
def check_recaptcha(f):
"""
Checks Google reCAPTCHA.
:param f: view function
:return: Function
"""
@wraps(f)
def decorated_function(*args, **kwargs):
request.recaptcha_is_valid = None
if request.method == 'POST':
data = {
'secret': GOOGLE_RECAPTCHA_SECRET_KEY,
'response': request.form.get('g-recaptcha-response'),
'remoteip': request.access_route[0]
}
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
flash('Invalid reCAPTCHA. Please try again.', 'error')
return f(*args, **kwargs)
return decorated_function
The last step is to decorate the view or views that you would like to use reCAPTCHA and test request.recaptcha_is_valid
for a truthy value:
@user.route('/login', methods=['GET', 'POST'])
@check_recaptcha
def login():
"""User login."""
if form.validate_on_submit() and request.recaptcha_is_valid:
# login user...
return render_template('user/login.jinja2', form=form)
That's it, done.