Flask中請求體的請求開啟CSRF保護可以按以下配置
from flask_wtf.csrf import CSRFProtect app.config.from_object(Config) CSRFProtect(app)
但CSRFProtect只做驗證工作,cookie中的 csrf_token 和表單中的 csrf_token 需要按以下方式實現
理清思路
根據 csrf_token 校驗原理,具體操作步驟有以下幾步:
- 后端生成 csrf_token 的值,在前端請求登錄或者注冊界面的時候將值傳給前端,傳給前端的方式可能有以下兩種:
- 在模板中的 From 表單中添加隱藏字段
- 將 csrf_token 使用 cookie 的方式傳給前端
- 在前端發起請求時,在表單或者在請求頭中帶上指定的 csrf_token
- 后端在接受到請求之后,取到前端發送過來的 csrf_token,與第1步生成的 csrf_token 的值進行校驗
- 如果校驗對 csrf_token 一致,則代表是正常的請求,否則可能是偽造請求,不予通過
而在 Flask 中,CSRFProtect 這個類專門只對指定 app 進行 csrf_token 校驗操作,所以開發者需要做以下幾件事情:
- 生成 csrf_token 的值
- 將 csrf_token 的值傳給前端瀏覽器
- 在前端請求時帶上 csrf_token 值
完成代碼邏輯
- 生成 csrf_token 的值
# 導入生成 csrf_token 值的函數 from flask_wtf.csrf import generate_csrf # 調用函數生成 csrf_token csrf_token = generate_csrf()
- 將 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
- 在前端請求時帶上 csrf_token 值
- 根據登錄和注冊的業務邏輯,當前采用的是 ajax 請求
- 所以在提交登錄或者注冊請求時,需要在請求頭中添加
X-CSRFToken
的鍵值對
$.ajax({ url:"/passport/register", type: "post", headers: { "X-CSRFToken": getCookie("csrf_token") }, data: JSON.stringify(params), contentType: "application/json", success: function (resp) { if (resp.errno == "0"){ // 刷新當前界面 location.reload() }else { $("#register-password-err").html(resp.errmsg) $("#register-password-err").show() } } })