一:安裝 flask_wtf
pip install flask_wtf
二:設置應用程序的 secret_key,用於加密生成的 csrf_token 的值
# session加密的時候已經配置過了.若是沒有在配置項中設置,則以下: app.secret_key = "#此處能夠寫隨機字符串#"
三:導入 flask_wtf.csrf 中的 CSRFProtect 類,進行初始化,並在初始化的時候關聯 app
from flask.ext.wtf import CSRFProtect
CSRFProtect(app)
四:在表單中使用 CSRF 令牌:
<form method="post" action="/"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" /> </form>
五:scrf的過程理解
代碼顯示方法不被容許的代碼html
#manage.py前端
from flask import Flask, render_template, request, g from settings.dev import DevConfig from flask.ext.wtf import CSRFProtect app = Flask(__name__, template_folder="templates", static_folder="static") app.config.from_object(DevConfig) CSRFProtect(app) # @app.route("/csrf_test", methods=["get", "post"]) @app.route("/csrf_test") def index(): if request.method == "GET": return render_template("form.html") else: print(request.form) return "ok" if __name__ == "__main__": app.run()
templates下的form.htmlweb
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>csrf案例</title> </head> <body> <form action="" method="post"> 帳號:<input type="text" name="username"><br><br> 密碼:<input type="password" name="password"><br><br> <input type="submit" value="提交"> </form> </body> </html>
運行後顯示的結果是:ajax
而後修改manage.py中的代碼,添加json
@app.route("/csrf_test", methods=["get", "post"])
代碼以下:flask
from flask import Flask, render_template, request, g from settings.dev import DevConfig from flask.ext.wtf import CSRFProtect app = Flask(__name__, template_folder="templates", static_folder="static") app.config.from_object(DevConfig) CSRFProtect(app) @app.route("/csrf_test", methods=["get", "post"]) def index(): if request.method == "GET": return render_template("form.html") else: print(request.form) return "ok" if __name__ == "__main__": app.run()
再次執行:而且提交:後端
說明須要在html文檔中添加:csrf_token瀏覽器
<input type="hidden" name="csrf_token" value="{{csrf_token()}}">
修改後的代碼是:cookie
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>csrf案例</title> </head> <body> <form action="" method="post"> <input type="hidden" name="csrf_token" value="{{csrf_token()}}"> 帳號:<input type="text" name="username"><br><br> 密碼:<input type="password" name="password"><br><br> <input type="submit" value="提交"> </form> </body> </html>
運行後的結果顯示:session
flask——CSRFToken保護
根據 csrf_token 校驗原理,具體操做步驟有如下幾步:
1.後端生成 csrf_token 的值,在前端請求登陸或者註冊界面的時候將值傳給前端,傳給前端的方式可能有如下兩種:
在模板中的 From 表單中添加隱藏字段
將 csrf_token 使用 cookie 的方式傳給前端
2.在前端發起請求時,在表單或者在請求頭中帶上指定的 csrf_token
3.後端在接受到請求以後,取到前端發送過來的 csrf_token,與第1步生成的 csrf_token 的值進行校驗
4.若是校驗對 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")#get_Cookie爲自定義函數 }, 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() } } })
flask csrf保護的使用技巧
CSRF(Cross-site request forgery)跨站請求僞造,也被稱爲「One Click Attack」或者Session Riding,一般縮寫爲CSRF或者XSRF,是一種對網站的惡意利用。 ——百度百科
網上關於csrf攻擊的一個最典型的例子是銀行經過url+參數轉錢的問題,很好理解。
flask 做爲一個強帶的web微框架,天然也是支持防範csrf攻擊的。
經過Flask-WTF來保護表單免受CSRF攻擊
何爲Flask-WTF
簡單說來,使用它能夠方便咱們構建表單和驗證表單,具體用法這裏不作贅述
怎麼開啓保護?
極少的配置,一個應用令牌:
app.config['SECRET_KEY'] = 'you can't know' 或csrf專用令牌 app.config['WTF_CSRF_SECRET_KEY'] = 'IT 666 to 709 kill pic'
Flask-WTF默認是開啓CSRF保護的,你須要的作的是在你的模板中表單一欄加入:
{{ form.csrf_token }}
或者
{{ form.hidden_tag() }}
這樣,csrf保護已經開啓。如若你沒有上面的代碼,提交表單會沒法經過form.validate_on_submit()
,錯誤爲
{'csrf_token': ['The CSRF token is missing.']},但這並不會致使http錯誤,僅是沒法經過驗證。
關閉保護
天然,咱們極可能有的表單不須要保護,那麼,如下三種:
全局禁用:app.config中設置WTF_CSRF_ENABLED = False
單個表單禁用:生成表單時加入參數form = Form(csrf_enabled=False)
不使用Flask-WTF…啊啊,這個很好理解
http://docs.jinkan.org/docs/flask-wtf/from.html
flask 內置的保護機制
有些時候,我根本就用不到Flask-WTF,那麼我可使用flask自身提供的保護機制。
開啓保護
要開啓csrf攻擊保護,須要一下幾個步驟。
from flask_wtf.csrf import CSRFProtect app.config['SECRET_KEY'] = 'you never guess' CSRFProtect(app)
主要爲:導入方法,設置密鑰,進行保護。
這時候對於一個普通的form,若是你沒有
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
flask會拋出http錯誤。
臨時關閉保護
那麼,如何臨時關閉csrf保護呢。
上面的代碼作修改:
去掉 CSRFProtect(app) 改成 csrf = CSRFProtect() if __name__ == '__main__':中加入 csrf.init_app(app) 在不須要保護的路由上當加上: @csrf.exempt
如此,臨時關閉了csrf。