由于Flask-WTF的CSRF保护,Flask-Restful POST失败

时间:2014-02-02 10:57:26

标签: python rest flask flask-wtforms flask-restful

我正在使用普通烧瓶网+烧瓶 - 安静。所以我需要针对Web的CSRF保护,而不是REST。

我启用CsrfProtect(app)的{​​{1}}时,我flask-wtf的所有单位测试都会返回400。

是否有办法为REST服务禁用CSRF保护,因为它们来自手机而无需会话处理,因此CSRF没有多大意义。

这是我测试它的方式:

flask-restful

6 个答案:

答案 0 :(得分:15)

您可以使用@csrf.exempt decorator,直接在API对象上添加decorators argument;这会将装饰器应用于所有 API路径:

csrf_protect = CsrfProtect(app)
api = restful.Api(app, decorators=[csrf_protect.exempt])

您不能使用resource method decorators,因为它们不是exempt装饰器需要工作的最终视图函数。

看来你无法保护个人资源并豁免他人;这是Flask-Wtf记录哪些视图被豁免的方法所使用的方法的限制。

答案 1 :(得分:3)

更简单的解决方案(related commit):

csrf.exempt(api_blueprint)

这是一个完整的演示:

from flask import Flask, Blueprint
from flask_wtf import CSRFProtect

app = Flask(__name__)
csrf = CSRFprotect(app)

api_blueprint = Blueprint('api', __name__)
csrf.exempt(api_blueprint)

app.register_blueprint(api_blueprint)

答案 2 :(得分:0)

我遇到了完全相同的问题,并且我不断收到通用401未经授权的错误,而我的邮递员电话工作得很好。我花了一段时间才弄清楚这是因为我为基于Web的表单启用了CSRF。但是我的后端呼叫是由Restful终结点提供的,CSRF Protection不适用于Restful呼叫。

这是我的固定方法:

在我的设置文件中

我将JWT_COOKIE_CSRF_PROTECT设置为False,并修复了我烦躁的帖子调用。

注意:

由于您是在全局设置文件中设置此字段的,因此此操作将禁用所有API调用的CSRF保护。

答案 3 :(得分:0)

您还可以通过将WTF_CSRF_ENABLED设置为False来取消CSRF保护。这在您的单元测试中很方便。例如,当您创建用于单元测试的测试应用并禁用WTF_CSRF_ENABLED时,测试不应抛出CSRF令牌丢失错误:

app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping({'WTF_CSRF_ENABLED':False})
app.test_client().get("/api/v1/")

答案 4 :(得分:0)

可以通过使用@ app.before_request装饰器检查路径并按需激活保护来解决CSRF保护烧瓶不稳定蓝图上的单个API端点的变通方法。

@app.before_request
def csrf_protect():
    if request.path.startswith("/api/v1/resource"):
        csrf.protect()

前提条件是您已设置设置

WTF_CSRF_CHECK_DEFAULT = False

答案 5 :(得分:-1)

您可以在test_config中设置WTF_CSRF_ENABLED = False。 如果您只想为您的测试禁用它。