Search code examples
htmlflaskrecaptchaflask-wtforms

Validating for reCAPTCHA in flask


I'm making an error form on my website and it still works fine except for the captcha which is a bit silly. If I fill in all the fields on the text and do not just fill in the captcha, it will still be sent to me and without warning or anything, my validations that I set there will not respond, I need to help with it.

HTML Code:

<form action="{{ url_for('get_contact') }}" method=post>
            <div>
                <p>
                    {{ form.csrf_token }}
                    {{ form.name.label }} <br>
                    {{ form.name(placeholder='Jméno') }}
                    <ul>
                        {% for error in form.name.errors %}
                            <li style="color:red;">{{ error }}</li>
                        {% endfor %}
                    </ul>
                <p>
                    {{ form.email.label }} <br>
                    {{ form.email(placeholder='Email') }}
                    <ul> 
                        {% for error in form.email.error %}
                           <li style="color:red;">{{ error }}</li> 
                        {% endfor %}
                        </ul>
                </p>
                <p>
                    {{ form.message.label }}<br>
                    {{ form.message(placeholder='Zpráva') }}
                </p>
                <p>
                    {{ form.recaptcha }}
                    {% for error in form.recaptcha.errors %}
                    <ul>
                        <li>{{ error }}</li>
                    {% endfor %}
                    </ul>
                    <input class="contact-submit" type="submit" value="Submit">

Flask Code:

@app.route('/contact', methods=["GET","POST"])
def get_contact():
    form = ContactForm()
    if request.method == 'POST':
        name =  request.form["name"]
        email = request.form["email"]
        message = request.form["message"]
        res = pd.DataFrame({'name':name, 'email':email, 'message':message}, index=[0])
        res.to_csv('./contactDatabase.csv', mode='a', header =False)
        return redirect(url_for("rgb"))
    else:
        return render_template('contact.html', form=form)

Flask forms code:

class ContactForm(FlaskForm):
    name = TextField("Jméno", [validators.DataRequired(), validators.Length(max=255)])
    email = StringField("Email", [validators.DataRequired(), validators.Length(min=6, max=35)])
    message = TextAreaField("Zpráva")
    recaptcha = RecaptchaField()

Solution

    1. You may have forgotten to use form.validate_on_submit()
    @app.route('/contact', methods=["GET","POST"])
    def get_contact():
        form = ContactForm()
        if request.method == 'POST' and form.validate_on_submit():
            name =  form.name
            email = form.email
            message = form.message
            res = pd.DataFrame({'name':name, 'email':email, 'message':message}, index=[0])
            res.to_csv('./contactDatabase.csv', mode='a', header =False)
            return redirect(url_for("rgb"))
        else:
            return render_template('contact.html', form=form)
    

    I didn't test the code above so I don't know if it's working.

    1. Check if app.testing is True. 1

    The flask-wtforms documentation states that:

    For your convenience, when testing your application, if app.testing is True, the recaptcha field will always be valid.

    1. Also, don't forget you have to set the RECAPTCHA_PUBLIC_KEY and RECAPTCHA_PRIVATE_KEY configuration variables with the respective public and private keys received from your ReCaptcha registration.

    1 It returns True if you set it to True directly or setting TESTING to True.