我创建了一个API,可以应对移动设备和Web浏览器。例如,/web/toys
表示网络,/API/toys
表示JSON响应。我使用JW Tokens作为身份验证方法。
我在HTML和后台显示表单,我调用jQuery Ajax的方法来POST我的API。我将access_tokens保留在会话cookie中。为了防止CSRF攻击,我使用的是Flask-JWT-Extended。
当我用@jwt_required
装饰一个视图并且CSRF设置为True时,即使设置和转移了cookie,我也会获得missing JWT in headers and cookies
。我检查了源代码,发现在请求标头中设置X-CSRF-TOKEN
很重要。
但是,由于端点同时响应GET和POST调用,如何在GET调用中设置标头而不需要使用jQuery加载整个页面。?
基本上,我想显示表单在网页上,当用户点击提交时,表单将使用jQuery传输到现有API。
如果有更好的办法来处理事情,我很想知道。
谢谢!
答案 0 :(得分:0)
Flask-JWT-Extended的作者在这里。正如您所发现的,通过此扩展,我们目前正在为每种类型的请求进行CSRF保护。但是,仅在状态更改请求时才需要CSRF保护:请参阅:https://security.stackexchange.com/questions/115794/should-i-use-csrf-protection-for-get-requests/115800
保护所有请求类型的好处是,如果您的端点在GET请求中错误地更改了状态(没有技术原因,这不会发生),它就容易受到CSRF攻击。现在,如果后端的设计更符合规格,那么这就不再是问题了。听起来我需要更新Flask-JWT-Extended以允许忽略某些类型请求的CSRF保护,就像Flask-WTF的运行方式一样。我今天会尝试更新。
或者,如果您的后端直接提供JSON而不是html(例如REST api后端和javascript前端),则可以使用Ajax使用CSRF令牌执行GET请求。在这个用例中,我们可以沿着这些行使用Ajax调用。
get (options) {
let self = this
$.ajax({
method: 'GET',
dataType: 'json',
headers: {
'X-CSRF-TOKEN': Cookies.get('csrf_access_token')
},
url: "some_url",
success (result, statusText) {
// Handle success
},
error (jqXHR, textStatus, errorThrown) {
//handle error
}
})
}
编辑:如果CSRF令牌不存在且您正在为JWT使用标头和Cookie,我还希望保留CSRF错误消息。可以在这里跟踪这两方面的进展: