如何在AJAX中使用Flask-WTForms CSRF保护?

时间:2015-08-08 00:15:26

标签: python flask flask-wtforms csrf-protection

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?

2 个答案:

答案 0 :(得分:16)

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)
        }
    }
})

希望这有帮助!

答案 1 :(得分:0)

我认为 !/^ 是一个否定断言,因此如果请求与 Get/Head 等不匹配且未跨域,则使用 csrf 令牌的值设置请求标头