Flask-wtf:csrf_token从会话中删除,然后我可以发布我的表单 [英] Flask-wtf: csrf_token is removed from session before I can POST my form
问题描述
render:function(){
var self = this;
$ .ajax({
type:'GET',
url:Config.constants.serverGateway +/ register
})。done(function(result){
console.log(get register done,result);
var html = self.template({config:Config,form:result});
self。$ el.html(html );
})。fail(function(error){
console.log(Could not get register token,error);
var html = this.errorTemplate({config:Config });
self。$ el.html(html);
});
返回这个;
}
这样我就产生了csrf,当我POST注册数据时,我发送正确的csrf沿用户数据(电子邮件和密码)。
submit:function(){
console .LOG( 提交);
var self = this;
var formData = this。$ el.find('form')。serialize(); $ b $ .ajax({
type:'POST',
url:Config.constants.serverGateway +/ register,
data:formData,
dataType: 'json'
})。done(function(result){
self.trigger('close');
})。fail(function(error){
console。日志(无法提交注册数据,错误);
});
$ b $ p
$ b 在服务器端,我可以调试我的Python代码,当我请求注册页面时生成的csrf_token已从会话对象中消失,因此导致产生一个新的,这当然不符合我发送的表单。会话仍然是相同的,因为_id在GET和POST期间是相同的。
您可以在flask_wtf / csrf.py :: generate_csrf (),在从flask_security / views.py中创建:: register函数中的表单对象时调用。
$ b $ pre $ 如果'csrf_token '不在会话中:
session ['csrf_token'] = hashlib.sha1(os.urandom(64))。hexdigest()
导致CSRF TOKEN MISSING错误。
另一个信息是,我的前端和后端交付由相同的服务器,因为他们有一个不同的端口号。
最后,当我在前端使用href并显示由服务器在' GET'请求,提交表单运行良好。
感谢您的帮助
好吧,我终于想出了解决我的问题的方法。我感觉像一个noob(我是)。
这个问题在于会话证书中没有被发送到服务器的请求,所以服务器coudldn'访问会话cookie。
我在下面的教程中找到了解决方案: http://backbonetutorials.com/cross-domain / b>
//使用withCredentials来发送服务器的cookie
//服务器必须通过响应头允许这个
$ .ajaxPrefilter(function(options,originalOptions,jqXHR){
options.xhrFields = {
withCredentials:true
};
});
这使得所有的AJAX请求都包含 withCredentials = true
。在服务器端,我必须设置 Access-Control-Allow-Credentials:true
。因为我正在使用flask-cors,所以在创建CORS对象时使用 [supports_credentials = True] [2]
来完成。
I'm using Flask with Flask-Security (specifically Flask-WTF regarding my csrf issue) to "ease" the process of register/loggin users (not easy so far). I'm using BackboneJS on the front-end, therefore I kind of hacked the original way to use Flask-WTF. Indeed, I make an AJAX GET request on /register to get the register page (generated by Flask-Security) and I put the resulting HTML in a modal.
render: function () {
var self = this;
$.ajax({
type: 'GET',
url: Config.constants.serverGateway + "/register"
}).done(function(result){
console.log("get register done", result);
var html = self.template({ config: Config, form: result });
self.$el.html(html);
}).fail(function(error){
console.log("Could not get register token", error);
var html = this.errorTemplate({ config: Config });
self.$el.html(html);
});
return this;
}
This way I have the generated csrf, and when I POST the registration data, I send the right csrf along the user data (email and password).
submit: function () {
console.log("submit");
var self = this;
var formData = this.$el.find('form').serialize();
$.ajax({
type: 'POST',
url: Config.constants.serverGateway + "/register",
data: formData,
dataType: 'json'
}).done(function(result){
self.trigger('close');
}).fail(function(error){
console.log("Could not submit register data", error);
});
}
On the server-side, I can debug my python code to see that the csrf_token which has been generated when I requested the register page has disappeared from the session object, therefore leading to the generation of a new one, which of course didn't match the one I send with my form. The session is still the same though, as the _id is the same during the GET and the POST.
You can see the code in flask_wtf/csrf.py::generate_csrf(), which is called when creating the form object in the ::register function from flask_security/views.py
if 'csrf_token' not in session:
session['csrf_token'] = hashlib.sha1(os.urandom(64)).hexdigest()
It results in a CSRF TOKEN MISSING error.
An additionnal information, is that my front-end and back-end are delivered by the same server, as they have a different port number.
Last, when I use an href on front-end and display the page returned by the server on the 'GET' request, submitting the form works well. I just liked to display this registration form in a modal.
Thanks for your help
Okay, I finally figured out the solution to my problem. I feel like a noob (which I am).
The problem lied in the session credentials which were not sent to the server with the requests, so that the server coudldn't access the session cookie. I found the solution in the following tutorial: http://backbonetutorials.com/cross-domain-sessions/ To send it, i added the following lines in my Backbone router initialize function:
// Use withCredentials to send the server cookies
// The server must allow this through response headers
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.xhrFields = {
withCredentials: true
};
});
This makes all AJAX requests include the withCredentials = true
. On the server-side, I had to set Access-Control-Allow-Credentials:true
. Since I'm using flask-cors, it is done with [supports_credentials=True][2]
when creating the CORS object.
这篇关于Flask-wtf:csrf_token从会话中删除,然后我可以发布我的表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!