Django之CSRF

網頁向後端傳送數據的時候有兩種方式,get和post。經過設置form中的method來達到是否採用get或者是postajax

<form action="/show_all/" method="POST">
可是django中使用post的話會遇到以下的錯誤

這個錯誤的意思是csrf校驗失敗,request請求被丟棄掉。咱們先來了解下什麼是csrf。django

CSRF, Cross Site Request Forgery, 跨站點僞造請求。舉例來說,某個惡意的網站上有一個指向你的網站的連接,若是某個用戶已經登陸到你的網站上了,那麼當這個用戶點擊這個惡意網站上的那個連接時,就會向你的網站發來一個請求,你的網站會覺得這個請求是用戶本身發來的,其實呢,這個請求是那個惡意網站僞造後端

舉個例子:瀏覽器

假如用戶abc登陸了銀行的網站,而且向abc2進行了轉帳,對銀行發送的請求是 http://bank.example/withdraw?account=abc&amount=1000000&for=abc2. 一般狀況下,請求發送到服務器後,服務器會首先驗證是不是合法的session,若是是則轉帳成功。假設黑客也有一樣銀行的帳號。他知道轉帳的時候會生成如上的請求連接。黑客也能夠發送一樣的請求給服務器要求轉帳給本身。可是服務器校驗他的這個請求不是合法的session。所以黑客想到了CSRF的方式。他本身作一個網站,在網站中發下以下連接:http://bank.example/withdraw?account=abc&amount=1000000&for=heike 而且經過廣告或其餘的方式誘使abc點擊這個連接,上述 url 就會從 abc的瀏覽器發向銀行,而這個請求會附帶 abc瀏覽器中的 cookie 一塊兒發向銀行服務器。大多數狀況下,該請求會失敗,由於他要求 abc 的認證信息。可是,若是 abc 當時恰巧剛訪問他的銀行後不久,他的瀏覽器與銀行網站之間的 session 還沒有過時,瀏覽器的 cookie 之中含有 abc 的認證信息。這時,悲劇發生了,這個 url 請求就會獲得響應,錢將從 abc 的帳號轉移到黑客的帳號,而 abc 當時絕不知情安全

那麼解決辦法是什麼呢:服務器

CSRF 攻擊之因此可以成功,是由於黑客能夠徹底僞造用戶的請求,該請求中全部的用戶驗證信息都是存在於 cookie 中,所以黑客能夠在不知道這些驗證信息的狀況下直接利用用戶本身的 cookie 來經過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能僞造的信息,而且該信息不存在於 cookie 之中。能夠在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端創建一個攔截器來驗證這個 token,若是請求中沒有 token 或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。cookie

那麼回到django中的post失敗有兩種解決辦法:session

解決辦法一:將csrf中間層註釋掉ide

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
#    'django.middleware.csrf.CsrfViewMiddleware',
   
'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
此時將不會進行csrf的校驗,但如前面所述,這是一種不安全的行爲。並且djano也不推薦使用
 
解決辦法二:
在前面的提示中有這樣一句話:

In any template that uses a POST form, use the csrf_token tag inside the <form> element if the form is for an internal URL, e.g.:post

<form action="" method="post">{% csrf_token %}

也就是說在網頁中加入csrf_token的標籤就能夠經過csrf校驗
Django 提供的 CSRF 防禦機制:
1 django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 裏。而後每次 POST 請求都會帶上這個 token,這樣就能避免被 CSRF 攻擊。
2 在返回的 HTTP 響應的 cookie 裏,django 會爲你添加一個 csrftoken 字段,其值爲一個自動生成的 token,在全部的 POST 表單時,必須包含一個 csrfmiddlewaretoken 字段 (只須要在模板里加一個 tag, django 就會自動幫你生成,見下面)
3 在處理 POST 請求以前,django 會驗證這個請求的 cookie 裏的 csrftoken 字段的值和提交的表單裏的 csrfmiddlewaretoken 字段的值是否同樣。若是同樣,則代表這是一個合法的請求,不然,這個請求多是來自於別人的 csrf 攻擊,返回 403 Forbidden.
4 在全部 ajax POST 請求裏,添加一個 X-CSRFTOKEN header,其值爲 cookie 裏的 csrftoken 的值
相關文章
相關標籤/搜索