Flask-WTF CSRF 保护 & ajax 400 解决方法

一、配置

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()
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容