Django 的 CSRF 保護機制
阿新 • • 發佈:2018-06-13
ken 渲染 _for ID 一個 RF oss RM ext
用 django 有多久,我跟 csrf 這個概念打交道就有久了。
- 每次初始化一個項目時都能看到 django.middleware.csrf.CsrfViewMiddleware 這個中間件
- 每次在模板裏寫 form 時都知道要加一個 {% csrf_token %} tag
- 每次發 ajax POST 請求,都需要加一個 X_CSRFTOKEN 的 header
但是一直我都是知其然而不知其所以然,沒有把 csrf 的機制弄清楚。昨天稍微研究了一下,總結如下。
什麽是 CSRF
CSRF, Cross Site Request Forgery, 跨站點偽造請求。舉例來講,某個惡意的網站上有一個指向你的網站的鏈接,如果
某個用戶已經登錄到你的網站上了,那麽當這個用戶點擊這個惡意網站上的那個鏈接時,就會向你的網站發來一個請求,
你的網站會以為這個請求是用戶自己發來的,其實呢,這個請求是那個惡意網站偽造的。
具體的細節及其危害見 wikipedia
Django 提供的 CSRF 防護機制
django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 裏。然後每次 POST 請求都會帶上這個 token,
這樣就能避免被 CSRF 攻擊。
- 在返回的 HTTP 響應的 cookie 裏,django 會為你添加一個 csrftoken 字段,其值為一個自動生成的 token
- 在所有的 POST 表單時,必須包含一個 csrfmiddlewaretoken 字段 (只需要在模板裏加一個 tag, django 就會自動幫你生成,見下面)
- 在處理 POST 請求之前,django 會驗證這個請求的 cookie 裏的 csrftoken 字段的值和提交的表單裏的 csrfmiddlewaretoken 字段的值是否一樣。如果一樣,則表明這是一個合法的請求,否則,這個請求可能是來自於別人的 csrf 攻擊,返回 403 Forbidden.
- 在所有 ajax POST 請求裏,添加一個 X-CSRFTOKEN header,其值為 cookie 裏的 csrftoken 的值
Django 裏如何使用 CSRF 防護
- 首先,最基本的原則是:GET 請求不要用有副作用。也就是說任何處理 GET 請求的代碼對資源的訪問都一定要是“只讀“的。
- 要啟用 django.middleware.csrf.CsrfViewMiddleware 這個中間件
- 再次,在所有的 POST 表單元素時,需要加上一個 {% csrf_token %} tag
- 在渲染模塊時,使用 RequestContext。RequestContext 會處理 csrf_token 這個 tag, 從而自動為表單添加一個名為 csrfmiddlewaretoken 的 input
方法一:
在發送post請求的html頁面前加入{% csrf_token %}
方法二:
在處理post數據的view前加@csrf_exempt裝飾符
@csrf_exempt def profile_delte(request): del_file=request.POST.get("delete_file",‘‘)
Django 的 CSRF 保護機制