我使用 Flask 和 Flask-Security(特别是关于我的 csrf 问题的 Flask-WTF)来“简化”用户注册/登录的过程(到目前为止并不容易)。我在前端使用 BackboneJS,因此我有点破解了使用 Flask-WTF 的原始方法。事实上,我在 /register 上发出 AJAX GET 请求来获取注册页面(由 Flask-Security 生成),并将生成的 HTML 放入模式中。
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;
}
这样我就有了生成的 csrf,当我发布注册数据时,我会发送正确的 csrf 以及用户数据(电子邮件和密码)。
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);
});
}
在服务器端,我可以调试我的python代码,看到当我请求注册页面时生成的csrf_token已经从会话对象中消失,因此导致生成一个新的,这当然没有将我发送的表格与我的表格相匹配。但会话仍然相同,因为 GET 和 POST 期间的 _id 是相同的。
您可以在flask_wtf/csrf.py::generate_csrf()中看到代码,该代码是在flask_security/views.py中的::register函数中创建表单对象时调用的
if 'csrf_token' not in session:
session['csrf_token'] = hashlib.sha1(os.urandom(64)).hexdigest()
这会导致 CSRF TOKEN MISSING 错误。
附加信息是,我的前端和后端由同一台服务器提供,因为它们具有不同的端口号。
最后,当我在前端使用 href 并显示服务器在“GET”请求上返回的页面时,提交表单效果很好。我只是喜欢以模式显示此注册表单。
感谢您的帮助