在我的项目中__init__.py我有这个:
Letters
我的开发配置文件如下所示:
strptr
在我的unittest setUp中我有这个:
strptr
理论上,在这里将WTF_CSRF_ENABLED设置为False应该可以防止单元测试的CSRF,但是如果我在单元测试时进行POST,我仍然会遇到CSRF错误。我认为这是因为我已经调用了CsrfProtect(app)而WTF_CSRF_ENABLED为True(当我导入app时,它被调用)。如果我在配置文件中设置WTF_CSRF_ENABLED = False,它会按预期工作。
无论如何我可以在启用后禁用CSRF吗?或者我在这里咆哮错误的树?
答案 0 :(得分:7)
查看csrf_protect的代码,它会在每次请求进入时检查app.config ['WTF_CSRF_METHODS'],以查看此请求类型是否应受CSRF保护。默认情况下,受保护的方法是:
app.config.setdefault('WTF_CSRF_METHODS', ['POST', 'PUT', 'PATCH'])
因为它实际上每次都会检查app.config,只需将其更改为单元测试中的空列表setUp即可解决问题:
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来注销它。但我认为走这条路线更有可能在未来的更新中看到问题。
答案 1 :(得分:2)
如果这是一个选项,保持csrf_token
并不太难。我能够使用一些正则表达式并使用Flask docs中关于测试的登录功能成功登录到使用csrf_token
的应用程序。
def login(self, username, password):
rv = self.client.get('/login')
m = re.search(b'(<input id="csrf_token" name="csrf_token" type="hidden" value=")([-A-Za-z.0-9]+)', rv.data)
return self.client.post('/login', data=dict(
userName=username,
password=password,
csrf_token=m.group(2).decode("utf-8")
), follow_redirects=True)
所以我在这里做的是让csrf_token
成为第二个捕获组的一部分。这可以很容易地用于在整个应用程序中查找令牌。
答案 2 :(得分:2)
您可以使用配置变量WTF_CSRF_ENABLED
将其禁用,
例如
class TestConfig(Config):
TESTING = True
WTF_CSRF_ENABLED = False
...
或app.config['WTF_CSRF_ENABLED'] = False