This document provides practical code examples for integrating flask-simple-captcha into Flask applications.
This example, contributed by @TobiasTKranz, demonstrates integrating flask-simple-captcha with WTForms and Flask-Security in a Flask application.
In order to access the Simple Captcha Extension you might connect it to the flask extensions dict like that:
# Fake extension registration, to be able to access this extension's instance later on
app.extensions.update({"flask-simple-captcha": SIMPLE_CAPTCHA})import flask
from flask import current_app, request
from markupsafe import Markup
from wtforms import Field, ValidationError
SIMPLE_CAPTCHA_ERROR_CODES = {
"missing-input-hash": "The secret parameter is missing.",
"missing-input-response": "The response parameter is missing.",
"invalid-captcha-sol": "The captcha was not entered correctly.",
}
class SimpleCaptchaWidget:
def __call__(self, field, error=None, **kwargs):
simple_captcha = flask.current_app.extensions.get("flask-simple-captcha")
captcha_dict = simple_captcha.create()
return Markup(simple_captcha.captcha_html(captcha_dict))
class SimpleCaptcha:
def __init__(self):
self._simple_captcha = current_app.extensions.get("flask-simple-captcha")
def __call__(self, form, field):
if current_app.testing:
return True
request_data = request.json if request.is_json else request.form
c_hash = request_data.get('captcha-hash')
c_text = request_data.get('captcha-text')
if not c_hash:
raise ValidationError(
SIMPLE_CAPTCHA_ERROR_CODES["missing-input-hash"]
)
elif not c_text:
raise ValidationError(
SIMPLE_CAPTCHA_ERROR_CODES["missing-input-response"]
)
elif not self._validate_simple_captcha(c_hash, c_text):
raise ValidationError(
SIMPLE_CAPTCHA_ERROR_CODES["invalid-captcha-sol"]
)
def _validate_simple_captcha(self, c_hash, c_text):
return self._simple_captcha.verify(c_text, c_hash)
class SimpleCaptchaField(Field):
widget = SimpleCaptchaWidget()
def __init__(self, label="", validators=None, **kwargs):
validators = validators or [SimpleCaptcha()]
super().__init__(label, validators, **kwargs)Use the SimpleCaptchaField in your custom forms as follows:
from flask_security.forms import RegisterForm
from wtforms import StringField, DataRequired
class CustomRegisterForm(RegisterForm):
captcha = SimpleCaptchaField("Captcha")
first_name = StringField("First name", [DataRequired()])Include the CAPTCHA field in your HTML templates:
<form
action="{{ url_for_security('register') }}"
method="post"
name="register_user_form"
id="register_user_form"
>
<!-- ... other form elements ... -->
{{ render_field_with_errors(your_form.captcha, class_="form-control")}}
</form>