librelist archives

« back to archive

Flask Flask-WTF Apache form does not validate

Flask Flask-WTF Apache form does not validate

From:
Moritz Beber
Date:
2014-06-24 @ 16:14
Dear all,

I'm not sure whether this this is related to Flask or Flask-WTF but I
figure there are people knowledgeable about both here.

My problem is the following: I have a view with two forms (not sure
that having two forms is the culprit). I use a prefix for each and
check action in the following way:

if form1.is_submitted() and form1.submit.data and form1.validate():
    # yada yada

This works perfectly when I just run the Flask app by itself. However,
once I switch to Apache the form no longer validates but also does not
return an error (it should show up on the page). I log the contents of
flask.request.form and they are fine, form1.submit.data evaluates to
True but form1.validate() is False (without errors as mentioned).

Does anyone have an idea how the difference in form validation could
occur using Apache? I'm quite confused.

Best,
Moritz

Re: [flask] Flask Flask-WTF Apache form does not validate

From:
Bouni
Date:
2014-06-25 @ 12:50
Hi Moritz,

i can't say for shure where your problem comes from, but the way you 
validate the form looks strange to me.
Why not simply use:

if form1.validate_on_submit():
     # yada yada

I had a similar issue a while ago and as far as i remember it had to do 
with the value of the submit button which is sent to the webserver.
But i can't recall the exact problem :-/
You can try to log the submitted value of form1.submit.data for both 
cases to see if there is a difference.


Elias


Am 24.06.2014 18:14, schrieb Moritz Beber:
> Dear all,
> 
> I'm not sure whether this this is related to Flask or Flask-WTF but I
> figure there are people knowledgeable about both here.
> 
> My problem is the following: I have a view with two forms (not sure
> that having two forms is the culprit). I use a prefix for each and
> check action in the following way:
> 
> if form1.is_submitted() and form1.submit.data and form1.validate():
>     # yada yada
> 
> This works perfectly when I just run the Flask app by itself. However,
> once I switch to Apache the form no longer validates but also does not
> return an error (it should show up on the page). I log the contents of
> flask.request.form and they are fine, form1.submit.data evaluates to
> True but form1.validate() is False (without errors as mentioned).
> 
> Does anyone have an idea how the difference in form validation could
> occur using Apache? I'm quite confused.
> 
> Best,
> Moritz

Re: [flask] Flask Flask-WTF Apache form does not validate

From:
Moritz Beber
Date:
2014-06-25 @ 14:50
Hi,

Thank you for your reply.

> i can't say for shure where your problem comes from, but the way you
> validate the form looks strange to me.
> Why not simply use:
>
> if form1.validate_on_submit():
>      # yada yada
>
> I had a similar issue a while ago and as far as i remember it had to do
> with the value of the submit button which is sent to the webserver.

I did the if statement in that way so that it first tests whether that
was the form submitted before trying to validate it. That was to avoid
validation errors on the wrong form.

I reduced the code in order to test it further. I'm using the
following versions:

WTForms==2.0
Flask-WTF==0.9.5
Flask==0.10.1

 My form looks like this:

from flask.ext.wtf import Form
from wtforms import (StringField, SubmitField, SelectField, RadioField,
        SelectMultipleField, validators)

class TestForm(Form):
    time = RadioField("Time point", coerce=int,
            choices=[(2, "2 h"), (8, "8 h"), (24, "24 h")])
    dose = RadioField("Dosage",
            choices=[("Low", "Low"), ("Middle", "Medium"), ("High", "High")])
    submit = SubmitField("Go")

and the view function:

@app.route("/test/<int:time>/<dose>/", methods=["GET", "POST"])
def test_forms(time, dose):
    app.logger.debug(repr(flask.request.form))
    form = forms.TestForm(time=time, dose=dose)
    app.logger.debug("submitted: %r", form.is_submitted())
    app.logger.debug("form submit button: %r", form.submit.data)
    app.logger.debug("form valid: %r", form.validate())
    if form.is_submitted() and form.submit.data and form.validate():
        app.logger.debug("mission success")
        return flask.redirect(flask.url_for("test_forms",
                time=form.time.data, dose=form.dose.data))
    return flask.render_template("test_forms.html", form=form)

again this works perfectly if I run the Flask app on its own. However,
in Apache I get the following log entries:

ImmutableMultiDict([('csrf_token',
u'1403710594.65##89837ae8655dc5db304a4418cf5e407761a3a5a4'), ('time',
u'2'),
 ('submit', u'Go'), ('dose', u'Middle')])

submitted: True

form submit button: True

form valid: False

I really have no idea why the validation fails. Could it be related to
a messed up token? Is there a way to debug the 'validate' method?

Thanks for any advice,
Moritz

Re: [flask] Flask Flask-WTF Apache form does not validate

From:
Bouni
Date:
2014-06-25 @ 16:18
Try to log form.errors, maybe you see an error message that points you 
to the problem.
Another point is that you have not set any validators in your form, but 
try to validate it.
I'm not sure but maybe the validation fails if there are no validators 
defined.
Why this only happens in Apache is absolutely not clear to me :-/

Elias

Am 25.06.2014 16:50, schrieb Moritz Beber:
> Hi,
> 
> Thank you for your reply.
> 
>> i can't say for shure where your problem comes from, but the way you
>> validate the form looks strange to me.
>> Why not simply use:
>> 
>> if form1.validate_on_submit():
>>      # yada yada
>> 
>> I had a similar issue a while ago and as far as i remember it had to 
>> do
>> with the value of the submit button which is sent to the webserver.
> 
> I did the if statement in that way so that it first tests whether that
> was the form submitted before trying to validate it. That was to avoid
> validation errors on the wrong form.
> 
> I reduced the code in order to test it further. I'm using the
> following versions:
> 
> WTForms==2.0
> Flask-WTF==0.9.5
> Flask==0.10.1
> 
>  My form looks like this:
> 
> from flask.ext.wtf import Form
> from wtforms import (StringField, SubmitField, SelectField, RadioField,
>         SelectMultipleField, validators)
> 
> class TestForm(Form):
>     time = RadioField("Time point", coerce=int,
>             choices=[(2, "2 h"), (8, "8 h"), (24, "24 h")])
>     dose = RadioField("Dosage",
>             choices=[("Low", "Low"), ("Middle", "Medium"), ("High", 
> "High")])
>     submit = SubmitField("Go")
> 
> and the view function:
> 
> @app.route("/test/<int:time>/<dose>/", methods=["GET", "POST"])
> def test_forms(time, dose):
>     app.logger.debug(repr(flask.request.form))
>     form = forms.TestForm(time=time, dose=dose)
>     app.logger.debug("submitted: %r", form.is_submitted())
>     app.logger.debug("form submit button: %r", form.submit.data)
>     app.logger.debug("form valid: %r", form.validate())
>     if form.is_submitted() and form.submit.data and form.validate():
>         app.logger.debug("mission success")
>         return flask.redirect(flask.url_for("test_forms",
>                 time=form.time.data, dose=form.dose.data))
>     return flask.render_template("test_forms.html", form=form)
> 
> again this works perfectly if I run the Flask app on its own. However,
> in Apache I get the following log entries:
> 
> ImmutableMultiDict([('csrf_token',
> u'1403710594.65##89837ae8655dc5db304a4418cf5e407761a3a5a4'), ('time',
> u'2'),
>  ('submit', u'Go'), ('dose', u'Middle')])
> 
> submitted: True
> 
> form submit button: True
> 
> form valid: False
> 
> I really have no idea why the validation fails. Could it be related to
> a messed up token? Is there a way to debug the 'validate' method?
> 
> Thanks for any advice,
> Moritz

Re: [flask] Flask Flask-WTF Apache form does not validate

From:
Moritz Beber
Date:
2014-06-25 @ 18:20
On Wed, Jun 25, 2014 at 6:18 PM, Bouni <bouni@owee.de> wrote:
> Try to log form.errors, maybe you see an error message that points you
> to the problem.

Thank you for the pointer, the log indeed showed an error but I'm
stumped on how to deal with it:

form errors: {'csrf_token': ['CSRF token missing']}

since it does show up in the request args...

> Another point is that you have not set any validators in your form, but
> try to validate it.
> I'm not sure but maybe the validation fails if there are no validators
> defined.

I added validators and this is not the case.

Re: [flask] Flask Flask-WTF Apache form does not validate

From:
Moritz Beber
Date:
2014-06-25 @ 20:21
Researching this further I stumbled on your own post about csrf tokens Elias ^^

I'm using KV server side sessions and there seems to be a mismatch.
When I log the session contents at the end of the view I get:

<KVSession {'csrf_token': '4d6bddb500ce540ca7bdf7bac2f73d1789737d74'}>

whereas the HTML code shows:

<input id="csrf_token" name="csrf_token" type="hidden"
value="1403730513.34##0fbff2d0da65a355355a73c35f5832baad824576">

My module/__init__.py looks like the following:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from simplekv.memory import DictStore
from flaskext.kvsession import KVSessionExtension


app = Flask(__name__)
app.config.from_object("mymodule.config.Config")

db = SQLAlchemy(app)

store = DictStore()
KVSessionExtension(store, app)

from . import views

The csrf_token also seems to mismatch in development mode but does not
cause problems there for some reason.

Any ideas how to fix this mess?

Re: [flask] Flask Flask-WTF Apache form does not validate

From:
Moritz Beber
Date:
2014-06-26 @ 11:57
I've detailed my further findings and question in this SO question:


http://stackoverflow.com/questions/24427274/csrf-token-mismatch-in-apache-flask-due-to-session-reset