pallets-eco / flask-wtf

Simple integration of Flask and WTForms, including CSRF, file upload and Recaptcha integration.
https://flask-wtf.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.46k stars 308 forks source link

Recaptcha validator does not use field data #370

Open sr105 opened 5 years ago

sr105 commented 5 years ago

The Recaptcha validator grabs a specific field by name instead of using field.data (link to line below). This means that an HTML form must send the recaptcha value as g-recaptcha-response or the validator fails. Our frontend is a react app that does not use wtforms to generate the HTML. And uses the actual form field names inside POST data.

https://github.com/lepture/flask-wtf/blob/master/flask_wtf/recaptcha/validators.py#L40

class TokenForm(Form):
    """Evaluate login attempts with optional recaptcha."""

    email = StringField(validators=[validators.DataRequired()])
    password = StringField(validators=[validators.DataRequired()])
    recaptcha = RecaptchaField()

If the form data is passed as {... "recaptcha": "recaptcha_response_value"}, the validator fails even though it has the data in the passed field instance.

Our REST api and frontend rely on field names matching. Is there a workaround for this?

sr105 commented 5 years ago

Workaround:

from flask_wtf.recaptcha import Recaptcha

def validate_recaptcha(form, field):
    """Validate recaptcha response."""
    # Recaptcha validator only looks for data in a hard-coded field name
    # https://github.com/lepture/flask-wtf/issues/370
    request.json["g-recaptcha-response"] = field.data
    return Recaptcha()(form, field)