Flask Wtf是一個flask的表單插件,主要提供表單后臺驗證功能并自動為表單附加crsf_token的功能,其還有一個功能便是為所有視圖提供crsf驗證,通過附加在模板的{crsf_token()}渲染來獲得crsf_token,以便網(wǎng)頁的Ajax添加X-CSRFToken消息頭的填充。
文章著重講講crsf_token的功能,crsf_token可以有效的防止csrf的攻擊,當用戶被誘導進入釣魚網(wǎng)站并且進行表單的提交時,由于釣魚網(wǎng)站拿不到用戶的crsf_token從而提交無效。
表單的crsf_token功能的實現(xiàn):為所有的form添加一個crsf_token的隱藏值(FlaskForm繼承SecureForm,SecureForm中添加的crsf_token,通過CSRFTokenField以及HiddenField實現(xiàn)),從而攜帶至網(wǎng)頁的Form表單中,SecureForm中代碼如下:
self.csrf_token.current_token = self.generate_csrf_token(csrf_context)
其中generate_csrf_token被FlaskForm改寫了。
網(wǎng)頁的crsf_token需要用到Flask_Wtf的CsrfProtect并init_app之后方可生效,其核心方式如下:
@app.context_processord
def csrf_token():
@app.before_request
def _csrf_protect():
看完源碼都很好理解,需要注意的是crsf_token都會保存在session[token_key]中發(fā)送給發(fā)送給客戶端的cookie中,這樣返回的crsf_token不但會驗證真?zhèn)危?strong>SECRET_KEY)和過期時間,還會與解cookie獲得的session[token_key]進行比較,這帶來一個好處:在用戶登錄的過程中,可以通過這個crsf_token做一個防重放攻擊。因為每次網(wǎng)頁都要攜帶crsf_token并且用完就扔,監(jiān)聽者抓到登錄密碼密文和crsf_token時,crsf_token已經(jīng)過期,重放無效。
目前還有一個疑問,當網(wǎng)頁設置了crsf_token保護,而且網(wǎng)頁中存在表單時,crsf_token是否會算兩次?如果又同時存在多個表單,那會不會算很多次?不過多算幾次除了浪費資源倒不會有什么大問題。