起因:Ajax提示403錯誤
閒言碎語:據課程結束還有一週多,js殺我,要加油加油。
CSRF(Cross Site Request Forgery protection),中文簡稱跨站請求僞造。
django爲用戶實現防止跨站請求僞造的功能,通過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對於django中設置防跨站請求僞造功能有分爲全局和局部。
全局:
中間件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,爲當前函數強制設置防跨站請求僞造功能,即便settings中沒有設置全局中間件。
@csrf_exempt,取消當前函數防跨站請求僞造功能,即便settings中設置了全局中間件。
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect
原理:django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 裏。然後每次 POST 請求都會帶上這個 token,這樣就能避免被 CSRF 攻擊。
通過form表單提交
django中直接添加{% csrf_token%}
當查看頁面源碼時可以查看到有一個隱藏的input,示例:
通過ajax提交
因爲cookie中同樣存在csrftoken,所以可以在js中通過:
$.cooke(“cstftoken”)獲取
如果通過ajax進行提交數據,這裏提交的csrftoken是通過請求頭中存放,需要提交一個字典類型的數據,即這個時候需要一個key。
在views中的xxx函數中:
from django.conf import settings
然後print(settings.CSRF_HEADER_NAME)
這裏需要注意一個問題,這裏導入的settings並不是我們在項目文件下看到的settings.py文件,這裏是是一個全局的settings配置,而當我們在項目目錄下的settings.py中配置的時候,我們添加的配置則會覆蓋全局settings中的配置。
print(settings.CSRF_HEADER_NAME)打印的內容爲:HTTP_X_CSRFTOKEN
這裏的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以實際傳遞的是就是X_CSRFtoken,而在前端頁面的ajax傳遞的時候由於不能使用下劃線所以傳遞的是X_CSRFtoken。