如何通过 AJAX 使用 Flask-WTForms CSRF 保护?

Posted

技术标签:

【中文标题】如何通过 AJAX 使用 Flask-WTForms CSRF 保护?【英文标题】:How to use Flask-WTForms CSRF protection with AJAX? 【发布时间】:2015-10-31 12:33:39 【问题描述】:

Flask-WTForms 提供 CSRF 保护。它在使用普通 html 表单时效果很好,但在使用 AJAX 时过程不太清楚。我的表单中有一个文件上传,我使用 AJAX 将过程分成两部分:文件发送到 upload 端点,而表单的其余部分发送到 submit 端点。由于该文件是使用 AJAX 发布的,因此它没有获得 CSRF 令牌,但我想保护 upload 端点免受攻击。使用 AJAX 时如何生成 CSRF 令牌?

@app.route('/submit', methods=["GET","POST"])
@login_required
def submit():
    form = MyForm()

    if request.method == "POST" and form.validate():
        # success, csrf checks out and data is validated
        # do stuff

    csrf_for_uploads = # generate csrf?
    return render_template('some_form.html', form=form, csrf_for_uploads=csrf_for_uploads)

@app.route('/upload', methods=["POST"])
@login_required
def upload():
    myfile = request.files['file']
    # How do I verify CSRF now?

【问题讨论】:

【参考方案1】:

我在想 !/^ 是一个否定断言,所以如果请求不匹配 Get/Head 等且不跨域,则使用 csrf 令牌的值设置请求标头

【讨论】:

【参考方案2】:

documentation 谈到了关于 AJAX 实现 CSRF 保护的一些内容。

您可以启用该模块:

from flask_wtf.csrf import CsrfProtect

CsrfProtect(app)

然后在您的 AJAX POST 调用中使用它:

<meta name="csrf-token" content=" csrf_token() ">

var csrftoken = $('meta[name=csrf-token]').attr('content')

$.ajaxSetup(
    beforeSend: function(xhr, settings) 
        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) 
            xhr.setRequestHeader("X-CSRFToken", csrftoken)
        
    
)

希望这会有所帮助!

【讨论】:

嗯,我完全错过了那个文档。是的,总结得差不多了。 您好,请注意:“FlaskWTFDeprecationWarning:“flask_wtf.CsrfProtect”已重命名为“CSRFProtect”,将在 1.0 中删除。” 有人可以解释一下“if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain)”是什么意思吗?谢谢! 此解决方案依赖于使用 jinja 渲染模板。有没有办法做到这一点?比如在响应中传递令牌? 如何使用 fetch API 做到这一点?

以上是关于如何通过 AJAX 使用 Flask-WTForms CSRF 保护?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 AJAX 使用 Flask-WTForms CSRF 保护?

如何通过拖放上传多个文件并使用ajax浏览

如何使用制表工具通过ajax提供工具提示文本?

如何通过主干中的 ajax 调用使用模型渲染多个视图

如何通过 Jquery/AJAX 上传文件 [重复]

如何在 jquery 中创建关联数组并通过 ajax 发送以使用 php 解析?