11

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

在我启用CsrfProtect(app)的那一刻flask-wtf,我所有的后期单元测试都flask-restful返回 400。

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

这就是我测试它的方式:

rv = self.client.post('api/v1.0/verify-email', environ_base={'REMOTE_ADDR': '127.0.0.1'}, headers={'Content-Type':'application/json'}, data=json.dumps(data))
self.check_content_type(rv.headers)
eq_(rv.status_code, 412)
4

6 回答 6

24

您可以使用需要直接在 API 对象上添加的@csrf.exempt装饰器,并带有decorators参数; 这会将装饰器应用于所有API 路由:

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

您不能使用资源方法装饰器,因为它们不是exempt装饰器工作所需的最终视图函数。

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

于 2014-02-02T11:25:32.550 回答
7

更简单的解决方案(相关提交):

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)
于 2017-08-25T11:33:07.477 回答
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/")
于 2020-08-07T07:43:35.553 回答
0

我遇到了完全相同的问题,并且一直收到一个通用的 401 Unauthorized 错误,而我的邮递员电话工作得非常好。我花了一段时间才弄清楚这是因为我为基于 Web 的表单启用了 CSRF。但是我的后端调用由 Restful 端点提供服务,CSRF 保护不适用于 restful 调用。

这是我修复它的方法:

在我的设置文件中,

我将 JWT_COOKIE_CSRF_PROTECT 设置为 False 并修复了我平静的帖子调用。

笔记:

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

于 2018-07-10T14:01:28.397 回答
0

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

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

前提是您已经设置了设置

WTF_CSRF_CHECK_DEFAULT = False
于 2020-12-02T23:06:28.100 回答
-2

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

于 2017-03-15T12:56:32.433 回答