文章内容

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丢失。


如何解决这两个问题呢?

在模板文件中加入如下代码:

<meta name="csrf-token" content="{{ csrf_token() }}">

如果是 Form 表单,增加 CSRF 的方式如下:

<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>

在后惰性加载它:

from flask_wtf.csrf import CsrfProtect
csrf = CsrfProtect()
def create_app():
app = Flask(__name__)
csrf.init_app(app)

多个表单我是用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 保护


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - flask 多个form.csrf_token如何处理

分享到:

发表评论

评论列表

user-ico

Sapphire on 回复 有用(0

csrf.init_app(app),这样就算初始化并生成了csrf token吗? 这样生成后前端的html头的meta直接通过 {{csrf_tken()}}就能获取到吗? 通过ajaxSetup设置后,后端就能通过request.headers的消息获取到前端传过来的吗? 同时后端再请求之前判断前后端的token是否一致就可以知道是不是伪造的了吗?