文章内容
2018/7/21 17:06:27,作 者: 黄兵
flask 多个form.csrf_token如何处理
最近有一个页面有多个,但是每次只提交一个表单。使用
{{ form.csrf_token }}
保护表单,避免跨域请求。
但是当表单有多个{{ form.csrf_token }}的时候,id都是一样的,会出现如下提示:
[DOM] Found 2 elements with non-unique id #csrf_token: (More info: https://goo.gl/9p2vKq)
看看生成的html代码:
第一个表单:
第二个表单:
在同一个html文件中两个id都相同,所以才会出现上面问题。
同时如果后台获取的话,也会报错:
{'old_password': ['This field is required.'], 'password': ['This field is required.'], 'password2': ['This field is required.'], 'csrf_token': ['The CSRF token is missing.']}
The CSRF token is missing:CSRF丢失。
如何解决这两个问题呢?
在模板文件中加入如下代码:
如果是 Form 表单,增加 CSRF 的方式如下:
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
在后惰性加载它:
多个表单我是用ajax
的方式提交。
查看一下html文件,可以看到具体获得的csrf-token
。
javascript提交方式:
// Inject our CSRF token into our AJAX request.
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)
}
}
})
好了,通过以上的修改就可以避免在一个页面上有两个相同id,同时也会解决The CSRF token is missing的问题。
问题解决,有什么问题可以在下面给我留言。
参考资料:CSRF 保护
黄兵个人博客原创。
Sapphire on 回复 有用(0)
csrf.init_app(app),这样就算初始化并生成了csrf token吗? 这样生成后前端的html头的meta直接通过 {{csrf_tken()}}就能获取到吗? 通过ajaxSetup设置后,后端就能通过request.headers的消息获取到前端传过来的吗? 同时后端再请求之前判断前后端的token是否一致就可以知道是不是伪造的了吗?