AJAX 如何使用 Flask-WTForms CSRF 保护?
How to use Flask-WTForms CSRF protection with AJAX?
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?
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)
}
}
})
希望对您有所帮助!
我认为 !/^ 是一个否定断言,因此如果请求不匹配 Get/Head 等并且不跨域,则将请求 header 设置为 csrf 令牌的值
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?
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)
}
}
})
希望对您有所帮助!
我认为 !/^ 是一个否定断言,因此如果请求不匹配 Get/Head 等并且不跨域,则将请求 header 设置为 csrf 令牌的值