之前我們在寫項目時會把下面項目setting.py中的 這一句注釋掉:
'django.middleware.csrf.CsrfViewMiddleware',
如果不注釋這一句我們在輸入正確用戶名和密碼的情況下進行如下POST請求時會出錯:
瀏覽器會禁止我們提交,這里就涉及到CSRF
什么是CSRF ? 跨站請求偽造, 問題: 1. 釣魚網站的頁面和正經網站的頁面對瀏覽器來說有什么區別? (頁面是怎么來的?) 釣魚網站的頁面是由 釣魚網站的服務端給你返回的 正經網站的網頁是由 正經網站的服務端給你返回的
當注釋掉那一句:
遇到釣魚網站時會出現下面的情況:
其中正經的網站的html
<h1>正經的網站</h1> <form action="/transfer/" method="post"><p> 轉出: <input type="text" name="from"> </p> <p> 轉入: <input type="text" name="to"> </p> <p> 金額: <input type="text" name="money"> </p> <p> <input type="submit" value="轉賬"> </p> </form>
釣魚的網站的html
<h1>釣魚的網站</h1> <form action="http://127.0.0.1:8002/transfer/" method="post"> <p> 轉出: <input type="text" name="from"> </p> <p> 轉入: <input type="text" name=""> <input type="text" name="to" style="display: none" value="哪吒"> </p> <p> 金額: <input type="text" name="money"> </p> <p> <input type="submit" value="轉賬"> </p> </form>
解決辦法:
當正經的網站給你返回一個頁面的時候,偷偷的在你form表單中塞一個特殊的字符串,后端會記下這個字符串,當你發POST請求時候,后端會
從你提交的數據里面拿到那個特殊的字符串然后和存的字符串比對一下,如果能比對上就表示你這個請求是來自我這個正經網站的請求,但釣魚
網站就沒有這個特殊的字符串,正經的網站就不會處理這個POST請求。
Django中內置了一個專門處理csrf問題的中間件 django.middleware.csrf.CsrfViewMiddleware 這個中間件做的事情: 1. 在render返回頁面的時候,在頁面中塞了一個隱藏的input標簽 用法: 我們在頁面上 form表單 里面 寫上 {% csrf_token %} <input type="hidden" name="csrfmiddlewaretoken" value="8gthvLKulM7pqulNl2q3u46v1oEbKG7BSwg6qsHBv4zf0zj0UcbQmpbAdijqyhfE"> 2. 當你提交POST數據的時候,它幫你做校驗,如果校驗不通過就拒絕這次請求
正經的網站代碼修改如下:
<h1>正經的網站</h1> <form action="/transfer/" method="post"> {% csrf_token %} <p> 轉出: <input type="text" name="from"> </p> <p> 轉入: <input type="text" name="to"> </p> <p> 金額: <input type="text" name="money"> </p> <p> <input type="submit" value="轉賬"> </p> </form>
然后取消那一句注釋:
再次進入正經的網站就會出現:
而且每次刷新的時候value值都不一樣
在兩個網站上再次進行POST請求時:
以上所用相關代碼:

from django.shortcuts import render, redirect, HttpResponse # Create your views here. # def login(request): # if request.method == "POST": # # 取出數據 # user = request.POST.get("username") # pwd = request.POST.get("pwd") # # if user == "alex" and pwd =="dsb": # return redirect("http://www.luffycity.com") # # return render(request, "login.html") # 轉賬 def transfer(request): if request.method == "POST": from_ = request.POST.get("from") to_ = request.POST.get("to") money = request.POST.get("money") print("{} 給 {} 轉了 {}錢".format(from_, to_, money)) return HttpResponse("轉賬成功!") return render(request, "transfer.html")

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>正經的網站</h1> <form action="/transfer/" method="post"> {% csrf_token %} <p> 轉出: <input type="text" name="from"> </p> <p> 轉入: <input type="text" name="to"> </p> <p> 金額: <input type="text" name="money"> </p> <p> <input type="submit" value="轉賬"> </p> </form> </body> </html>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>釣魚的網站</h1> <form action="http://127.0.0.1:8002/transfer/" method="post"> <p> 轉出: <input type="text" name="from"> </p> <p> 轉入: <input type="text" name=""> <input type="text" name="to" style="display: none" value="哪吒"> </p> <p> 金額: <input type="text" name="money"> </p> <p> <input type="submit" value="轉賬"> </p> </form> </body> </html>