app里面还是要绑定CSRFProtect
from flask_wtf import CSRFProtect # flask_wtf 已经提供CSRF的防御手段
CSRFProtect(app) # 绑定app
登录页的js
$(function () {
$(\'#submit\').click(function (event) {
event.preventDefault(); // 阻止默认form提交表单行为
var email = $(\'input[name=email]\').val();
var password = $(\'input[name=password]\').val();
var csrf_token = $(\'input[name=csrf_token]\').val();
// ajax
$.post({
\'url\': \'/login/\',
\'data\': {
\'email\': email,
\'password\': password,
\'csrf_token\': csrf_token
},
\'success\': function (data) {
console.log(data)
},
\'fail\': function (error) {
console.log(error)
}
});
});
});
在页面里面引入js
登录邮箱: | |
密码: | |
请求页面
以上方法虽能使用csrf_token防御,可需要在每一个提交页面都写,flask推荐的方式是将csrf_token()放到meta标签下下,发送数据时,放到头部信息中
使用jinja的模板继承功能,base模板:
Title{% block head %}{% endblock %}
导航条
{% block body %}{% endblock %}
底部
登录页继承base模板
{% extends \'base.html\' %}
{% block head %}
{% endblock %}
{% block body %}
邮箱: | |
密码: | |
{% endblock %}
登录页的js,将csrf放到头部信息
$(function () {
$(\'#submit\').click(function (event) {
event.preventDefault(); // 阻止默认form提交表单行为
var email = $(\'input[name=email]\').val();
var password = $(\'input[name=password]\').val();
var csrf_token = $(\'meta[name=csrf_token]\').attr(\'content\');
//设置头部信息
$.ajaxSetup({
\'beforeSend\': function (xhr, settings) {
if(!/^(GET|HEAD|OPTIPNS|TRACE)$/i.test(settings.type) && !this.crossDomain){
xhr.setRequestHeader(\'X-CSRFToken\', csrf_token)
}
}
});
// ajax
$.post({
\'url\': \'/login/\',
\'data\': {
\'email\': email,
\'password\': password,
},
\'success\': function (data) {
console.log(data)
},
\'fail\': function (error) {
console.log(error)
}
});
});
});
访问
由于每个js请求都需要在头部信息里面添加此参数,所以可以将添加头部信息拿出来封装
封装一个统一的ajax,每次自动获取csrftoken并加到头部信息中
var http = {
\'get\':function (args) {
args[\'method\'] = \'get\';
this.ajax(args);
},
\'post\':function (args) {
args[\'method\'] = \'post\';
this.ajax(args);
},
\'ajax\':function (args) { // 将头部信息放到请求
this._ajaxSetup();
$.ajax(args);
},
\'_ajaxSetup\':function(){ // 将csrftoken放到头部信息
$.ajaxSetup({
\'beforeSend\': function (xhr, settings) {
if(!/^(GET|HEAD|OPTIPNS|TRACE)$/i.test(settings.type) && !this.crossDomain){
var csrf_token = $(\'meta[name=csrf_token]\').attr(\'content\'); // 获取csrf_token
xhr.setRequestHeader(\'X-CSRFToken\', csrf_token)
}
}
});
}
};
登录页的js,使用自定义的ajax机制
$(function () {
$(\'#submit\').click(function (event) {
event.preventDefault(); // 阻止默认form提交表单行为
var email = $(\'input[name=email]\').val();
var password = $(\'input[name=password]\').val();
// 使用自定义的ajax
http.post({
\'url\': \'/login/\',
\'data\': {
\'email\': email,
\'password\': password,
},
\'success\': function (data) {
console.log(data)
},
\'fail\': function (error) {
console.log(error)
}
});
});
});
base模板中导入ajax的js
Title{% block head %}{% endblock %}
导航条
{% block body %}{% endblock %}
底部
请求
这样发送请求的时候使用自己封装的ajax就可以实现每次发送请求的时候自动在头部信息加上csrftoken信息