flask中的csrf防御机制
flask中使用CSRFProtect
原理:
1、在前端请求登录或者注册界面的时候将后端生成 csrf_token 的值传给前端,传给前端的方式可能有以下两种:
- 在模板中的 From 表单中添加隐藏字段
- 将 csrf_token 使用 cookie 的方式传给前端
2、在用户点击提交表单的时候,在post请求的headers中添加{“X-CSRFToken”:getCookie(csrf_token)}
3、后端在接受到请求之后,取到前端发送过来的 csrf_token,与第1步生成的 csrf_token 的值进行校验
4、如果校验对 csrf_token 一致,则代表是正常的请求,否则可能是伪造请求,不予通过
而在 Flask 中,CSRFProtect 这个类专门只对指定 app 进行 csrf_token 校验操作,所以开发者需要做以下几件事情:
- 生成 csrf_token 的值
- 将 csrf_token 的值传给前端浏览器
- 在前端请求时带上 csrf_token 值
注:Flask-WTF支持跨站请求伪造保护,所以它会为你的表单类自动创建一个CSRF字段,你需要在表单里渲染这个字段:{{ form.csrf_token }}。
代码:
1、开启CSRF防护
在创建app实例的时候
from flask import Flask
from flask_wtf.csrf import CSRFProject
app=Flask(__name__)
# 设置SECRET_KEY,加密生成令牌(csrf_token),再用令牌验证表单数据是否正常;
app.config["SECRET_KEY"] = "aaaaaaaa"
#开启CSRF保护
CSRFProject(app)
2、在前端请求登录或者注册界面的时候将后端生成 csrf_token 的值传给前端(可以在请求勾子函数中完成此逻辑)
@app.after_request
def after_request(response):
# 调用函数生成 csrf_token
csrf_token = generate_csrf()
# 通过 cookie 将值传给前端
response.set_cookie("csrf_token", csrf_token)
return response
3、给post请求的ajax中的headers添加“X-CSRFToken”
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
# 发起post请求
req_json = JSON.stringify(req_data);
$.ajax({
url: "/api/v1_0/users",
type: "post",
data: req_json,
contentType: "application/json",//指明向后端发送的是json格式数据
dataType: "json",//指明从后端收到的数据是json格式的
headers:{
"X-CSRFToken":getCookie("csrf_token")
},
success: function (resp) {
if (resp.errno == 0) {
//注册成功,引导到主页界面
location.href = "/";
} else {
alert(resp.errmsg);
}
}
})
4、CSRFProtect会取出请求头中的X-CSRFToken(csrf_token)与第1步生成的 csrf_token 的值进行校验。