我正在使用普通烧瓶网+烧瓶 - 安静。所以我需要针对Web的CSRF保护,而不是REST。
我启用CsrfProtect(app)
的{{1}}时,我flask-wtf
的所有单位测试都会返回400。
是否有办法为REST服务禁用CSRF保护,因为它们来自手机而无需会话处理,因此CSRF没有多大意义。
这是我测试它的方式:
flask-restful
答案 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。 如果您只想为您的测试禁用它。