一、配置
from flask_wtf.csrf import CSRFProtect
...
csrf = CSRFProtect()
csrf.init_app(app)
...
1、如果模板中存在表单,不需要做任何事情,与之前一个样:
<form method="post" action="">
{{ form.csrf_token }}
</form>
2、但如果模板中没有表单,你仍然需要一个CSRF令牌:
<form method="post" action="">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>
3、只要没通过CSRF验证,都会返回400 相应,比如ajax调用。我们 可以自定义这个错误相应
@csrf.error_handler
def csrf_error(reason):
return render_template("csrf_error.html",reason=reason), 400
4、强烈建议对所有视图启用CSRF保护。但也提供了某些视图函数不需要保护的装饰器:
@csrf.exempt
@blueprint.route('/foo',methods=["GET","POST"])
def my_handler():
...
return jsonify()
二、AJAX
1、假设已经使用了CSRFProtect(app), 你可以通过 {{ csrf_token() }} 获取CSRF令牌。这个方法在每个模板中都可以使用,并不需要担心在没有表单时如何渲染CSRF令牌字段。
这里推荐的方式是在<meta> 标签中渲染CSRF令牌:
<meta name="csrf-token" content="{{ csrf_token() }}"
或在<script>标签中渲染同样可行:
<script type="text/javascript">
var csrftoken="{{ csrf_token() }}"
</script>
2、下面例子采用了在<meta>标签渲染的方式,在<script>中渲染会更简单,你无须担心没有响应的例子。
无论何时发送 AJAX POST 请求,为其添加 X-CSRFToken 头:
var csrftoken = $('meta[name=csrf-token]').attr('content');
$.ajaxSetup({
url: "#",
type: "POST",
traditional: true,
dataType:"json",
contentType: "application/json",
data: JSON.stringify({ // 此处必须作json转换
"varA": $("#varA").val(),
"varB":$("#varB").val(),
"varC":$("#varC").val(),
}),
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
}
})
接下来后台就可以取数据了
request.get_json()