2016-07-27 14 views
0

In meinen Projekten __init__.py ich dieses:Flask disable CSRF in Unittest

app = Flask(__name__) 
app.config.from_object('config') 
CsrfProtect(app) 
db = SQLAlchemy(app) 

Meine Entwicklung config-Datei wie folgt aussieht:

import os 
basedir = os.path.abspath(os.path.dirname(__file__)) 

DEBUG = True 
WTF_CSRF_ENABLED = True 
SECRET_KEY = 'supersecretkey' 
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'project.db') 
SQLALCHEMY_TRACK_MODIFICATIONS = False 

Und in meinem Unittest setUp Ich habe diese:

Theoretisch sollte das Setzen von WTF_CSRF_ENABLED auf False hier CSRF für die Komponententests verhindern, aber ich bekomme immer noch CSRF-Fehler, wenn ich Führen Sie während des Komponententests einen POST durch. Ich denke, das liegt daran, dass ich CsrfProtect (App) bereits aufgerufen habe, während WTF_CSRF_ENABLED True ist (wenn ich eine App importiere, wird sie aufgerufen). Wenn ich WTF_CSRF_ENABLED = False in der Konfigurationsdatei einstelle, funktioniert es wie erwartet.

Kann ich CSRF trotzdem deaktivieren, nachdem es bereits aktiviert wurde? Oder belle ich hier den falschen Baum an?

+0

Ich denke, sobald Sie App importieren, dass Code ausgeführt wird, wird es daher mit Ihrer Standardkonfiguration ausgeführt, so dass danach, wenn Sie Ihren Test machen, ist es egal, dass Sie die Konfiguration überschreiben – limbo

+0

Ja, das ist mein Gedanke auch. Ich hoffe, es gibt eine Möglichkeit, es nach der Tat zu deaktivieren, vielleicht nicht durch app.config, aber so etwas wie StopCsrfProtect (app) oder so. Aber das ist wahrscheinlich Wunschdenken. – vimalloc

+0

Ich denke, die einfachste Problemumgehung besteht darin, sie einfach mit deaktiviertem CSRF auszuführen, wenn Sie testen. – limbo

Antwort

4

Wenn Sie den Code für csrf_protect betrachten, prüft er jedes Mal, wenn eine Anfrage eingeht, ob die Anfrage CSRF-geschützt sein soll, app.config ['WTF_CSRF_METHODS']. Standardmäßig sind die geschützten Methoden:

app.config.setdefault('WTF_CSRF_METHODS', ['POST', 'PUT', 'PATCH']) 

Weil es tatsächlich die app.config prüft jedes Mal, dies einfach auf eine leere Liste Wechsel in meinem Unit-Tests setUp behebt das Problem:

from project import app, db 

class ExampleTest(unittest.TestCase): 
    def setUp(self): 
     app.config['TESTING'] = True 
     app.config['WTF_CSRF_METHODS'] = [] # This is the magic 
     app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' 
     self.app = app.test_client() 
     db.create_all() 

Alternetly, Es registriert den csrf-Schutz mit app.before_request(), daher denke ich, dass es möglich sein kann, die Registrierung aufzuheben, indem Sie die before request functions ändern. Aber ich denke, dass dieser Weg mit größerer Wahrscheinlichkeit Probleme bei zukünftigen Updates sehen würde.

+0

Erstellen Sie eine benutzerdefinierte Class-Erweiterungseinheit, testen und überschreiben Sie diese Konfiguration und verwenden Sie sie in anderen Testklassen – Kalanamith