it-swarm.com.de

Flask-WTF - validate_on_submit () wird niemals ausgeführt

Ich verwende Flask-WTF:

Hier ist meine Form:

from flask.ext.wtf import Form, TextField

class BookNewForm(Form):
    name = TextField('Name')

Hier ist der Controller:

@book.route('/book/new', methods=['GET', 'POST'])
def customers_new():
    form = BookNewForm()
    if form.is_submitted():
        print "submitted"
    if form.validate():
        print "valid"
    if form.validate_on_submit():
        flash("Successfully created a new book")
        return redirect(url_for('.books_show'))
    return render_template('views/books_new.html', form=form)

Das Problem ist nun, wenn Sie sich meine Druckanweisungen ansehen, werden immer die gesendeten Drucke gedruckt, NIEMALS werden jedoch gültige Werte ausgegeben, und validate_on_submit () wird niemals ausgeführt. Warum?

26
kadrian

Sie fügen das CSRF-Feld nicht in das HTML-Formular ein.

<form method=post>
    {{ form.csrf_token }}
    {{ form.name }}
    <input type=submit>
</form>

Nach dem Hinzufügen von form.csrf_token zur Vorlage ( docs ) wird das Formular wie erwartet validiert.

Fügen Sie nach der Überprüfung des Formulars print(form.errors) hinzu, um die aufgetretenen Fehler anzuzeigen. errors ist vor der Überprüfung leer. In diesem Fall wird ein Fehler angezeigt

@book.route('/book/new_no_csrf', methods=['GET', 'POST'])
def customers_new_no_csrf():
    form = BookNewForm()
    print(form.errors)

    if form.is_submitted():
        print "submitted"

    if form.validate():
        print "valid"

    print(form.errors)

    if form.validate_on_submit():
        flash("Successfully created a new book")
        return redirect(url_for('.books_show'))

    return render_template('books_new.html', form=form)
{}
submitted
{'csrf_token': [u'CSRF token missing']}
127.0.0.1 - - [29/May/2012 02:01:08] "POST /book/new_no_csrf HTTP/1.1" 200 -
127.0.0.1 - - [29/May/2012 02:01:08] "GET /favicon.ico HTTP/1.1" 404 -

Ich habe ein Beispiel für GitHub erstellt.

41
A.Ford

sie können Fehler drucken

print form.errors

oder 

app.logger.debug(form.errors)

und wenn Sie den csrf-Fehler erhalten haben, sollten Sie form.csrf_token in Ihre Vorlage setzen. 

11
kzfm

fügen Sie dies nach dem Tag in die HTML-Vorlagendatei ein:

 {{ form.csrf_token }} 
2
lihuanshuai

Dies ist mir aufgefallen, als ich versuchte, eine FormField zu rendern, die über meine FieldList in meiner Vorlage iteriert wird. Ich musste zwei hidden_tag-Elemente einbetten, eines für das FieldList-Formular und eines für das FieldForm-Formular. Durchsuchen Sie die Vorlagenkommentare nach dem Schlüsselwort "HIDDEN TAG".

class ParamRangeForm( FlaskForm ):
    minX = FloatField( )
    maxX = FloatField( )

class ParamRangesForm( FlaskForm ):
    paramRanges = FieldList( FormField( ParamRangeForm ) )
    submit      = SubmitField( 'Submit' )

    def loadParams( self ) :
        for paramName in ["p1" , "p2" , "p3", "p4"] :
            prf = ParamRangeForm( )
            prf.minX = -100.9#float('-inf')
            prf.maxX = 100.5#float('-inf')
            self.paramRanges.append_entry( prf )

...

  <form action="" method="POST" enctype="multipart/form-data">
    {{ rangesForm.hidden_tag() }} <!--#### HIDDEN TAG #1 -->
    <table>
      <!--Print Column Headers-->
      <thead>
      <tr>
        <th class="ColumnHeader">Parameter</td>
        <th class="ColumnHeader">Min</td>
        <th class="ColumnHeader">Max</td>
      </tr>
      </thead>

      <!--Print Parameter Rows-->
      <tbody>
      {% for paramRange in rangesForm.paramRanges %}
        <tr>
          {{ paramRange.hidden_tag() }} <!--#### HIDDEN TAG #2 -->
          <td>p{{ loop.index }}</td>
          <td>{{ paramRange.minX }}</td>
          <td>{{ paramRange.maxX }}</td>
        </tr>
      {% endfor %}
      </tbody>
    </table>
    </div>
    {{ rangesForm.submit() }}
  </form>
1
jxramos

Ich löschte die Flaschensitzung, wenn ich nicht vor jeder Anfrage angemeldet war. Dies verursachte dieses Problem.

@main.before_request
def before_request():
    if not current_user.is_authenticated():
        # TODO clean sessions may cause CSRF missing issue
        session.clear()
        print "Session Cleared"
        return redirect(url_for('auth.login'))
1
tourdownunder

Ich habe mehrere Stunden damit verbracht, ein Validierungsproblem mit Flask-WTF zu beheben. Das Problem war, wie viele andere, eine CSRF-Validierungsfrage. Meins wurde jedoch nicht durch eines der allgemeinen Probleme verursacht, die ich gefunden habe.

Die standardmäßige Flask-WTF-Implementierung von CSRF erfordert, dass zwei Dinge an den Browser geliefert werden.

One: Das versteckte CSRF-Formularfeld, z.

<input id="csrf_token" name="csrf_token" type="hidden" value="ImYzODdmZTdhYTRlMmNkYWRjYmRlYWFmZjQxMDllZTQ1OWZmYzg3MTki.XKvOPg.gUCkF9j-vg0PrL2PRH-v43GeHu0">

Two: Der HTTP-Antwortheader des Sitzungscookies, z.

Set-Cookie: session=eyJjc3JmX3Rva2VuIjoiZjM4N2ZlN2FhNGUyY2RhZGNiZGVhYWZmNDEwOWVlNDU5ZmZjODcxOSJ9.XKvOPg.a3-W62MHvaGVkv2GYCi-dgpLE3Y; HttpOnly; Path=/

Wenn eine dieser Optionen fehlt, kann der Browser die korrekte CSRF-Validierung nicht senden. Dies führt natürlich dazu, dass die Formularüberprüfung fehlschlägt.

Wenn das ausgeblendete Feld csrf_token Im Formular vorhanden ist, der Sitzungscookie jedoch fehlt, erhalten Sie beim Absenden des Formulars die folgende Antwort ...

Bad Request
The CSRF session token is missing.

In meinem Fall fehlte der Sitzungscookie aufgrund eines Fehlers in meinem Code. Ich musste einen benutzerdefinierten HTTP-Header für die gesamte Flask Site bereitstellen. Ich habe ihn so eingefügt ...

class LocalFlask(Flask):

    def process_response(self, response):
        response.headers['my-header'] = 'My Header Value'
        return response

app = LocalFlask(__name__)

Dies führt jedoch dazu, dass alles, was von der Methode Flask.response.headers Abhängt, fehlschlägt. Eines davon ist Flaks-WTF, das den HTTP-Header des Sitzungscookies setzt.

Dies kann gelöst werden, indem die Methode super() zur Klasse LocalFlask hinzugefügt wird, sodass sie Methoden aus der Klasse Flask erbt.

class LocalFlask(Flask):

    def process_response(self, response):
        response.headers['my-header'] = 'My Header Value'
        #LocalFlask inherits methods from Flask
        super(LocalFlask, self).process_response(response)
        return response

app = LocalFlask(__name__)
0
D. Morell

Ich denke, die API hat sich geändert. Vielleicht versuchen Sie es zu ändern 

from flask.ext.wtf import Form

zu:

from flask_wtf import Form
0
Kanav Anand