Flask在unittest中禁用CSRF

vim*_*loc 6 flask flask-wtforms

在我的项目中__init__.py我有这个:

app = Flask(__name__)
app.config.from_object('config')
CsrfProtect(app)
db = SQLAlchemy(app)
Run Code Online (Sandbox Code Playgroud)

我的开发配置文件如下所示:

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
Run Code Online (Sandbox Code Playgroud)

在我的unittest setUp中我有这个:

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()
Run Code Online (Sandbox Code Playgroud)

理论上,在这里将WTF_CSRF_ENABLED设置为False应该可以防止单元测试的CSRF,但是如果我在单元测试时进行POST,我仍然会遇到CSRF错误.我认为这是因为我已经调用了CsrfProtect(app)而WTF_CSRF_ENABLED为True(当我导入app时,它被调用).如果我在配置文件中设置WTF_CSRF_ENABLED = False,它将按预期工作.

无论如何我可以在启用后禁用CSRF吗?或者我在这里咆哮错误的树?

vim*_*loc 10

查看csrf_protect的代码,它会在每次请求进入时检查app.config ['WTF_CSRF_METHODS'],以查看此请求类型是否应受CSRF保护.默认情况下,受保护的方法是:

app.config.setdefault('WTF_CSRF_METHODS', ['POST', 'PUT', 'PATCH'])
Run Code Online (Sandbox Code Playgroud)

因为它实际上每次都会检查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()
Run Code Online (Sandbox Code Playgroud)

Alternetly,它确实用app.before_request()注册csrf保护,所以我认为可以通过修改before请求函数来注销它.但我认为走这条路线更有可能在未来的更新中看到问题.


Jor*_*tao 7

您可以使用config变量将其禁用WTF_CSRF_ENABLED

例如

class TestConfig(Config):
    TESTING = True
    WTF_CSRF_ENABLED = False
    ...
Run Code Online (Sandbox Code Playgroud)

要么 app.config['WTF_CSRF_ENABLED'] = False

另请参见flask-WTF文档

  • 谢谢,这个解决方案`app.config ['WTF_CSRF_ENABLED'] = False`对我有用,但被接受的答案无效。 (2认同)