2016-07-27 84 views
0

在我的項目的__init__.py我有這樣的:瓶禁用CSRF在單元測試

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

我的開發配置文件看起來像:

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 

而在我的單元測試設置I有這樣的:

from project import app, db 

class ExampleTest(unittest.TestCase): 
    def setUp(self): 
     app.config['TESTING'] = True 
     app.config['WTF_CSRF_ENABLED'] = False 
     app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' 
     self.app = app.test_client() 
     db.create_all() 

理論上,在這裏將WTF_CSRF_ENABLED設置爲False應該可以防止單元測試的CSRF,但是如果我仍然收到CSRF錯誤單元測試時做POST。我認爲這是因爲我已經調用CsrfProtect(app),而WTF_CSRF_ENABLED爲True(當我導入應用程序時,它被調用)。如果我在配置文件中設置了WTF_CSRF_ENABLED = False,它將按預期工作。

無論如何我可以禁用CSRF後,它已被啓用?或者我在這裏咆哮錯誤的樹?

+0

我認爲一旦你導入的應用程序代碼運行,因此它會運行你的默認配置,所以在那之後當你做你的測試時,無論你是否越界配置 – limbo

+0

是的,這也是我的想法。我希望有一種方法可以在事後禁用它,也許不是通過app.config,而是像StopCsrfProtect(app)之類的東西。但這可能是一廂情願的想法。 – vimalloc

+0

我想最簡單的解決方法就是在測試時禁用CSRF來運行它。 – limbo

回答

4

查看csrf_protect的代碼,每次請求進來時都會檢查app.config ['WTF_CSRF_METHODS'],看看這個請求類型是否應該受CSRF保護。默認情況下,受保護的方法是:

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

,因爲它實際上檢查每一次的app.config,簡單地改變這在我的單元測試出現一個空的列表可以解決此問題:

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,它確實使用app.before_request()註冊了csrf保護,所以我認爲可以通過修改before request functions來取消註冊。但我認爲,走這條路可能會在未來的更新中看到問題。

+0

創建一個自定義類擴展單元測試並覆蓋此配置,並在其他測試類中使用它 – Kalanamith