2016-07-27 76 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