目錄
csrf介紹
什麼是csrf?
csrf:跨站請求偽造。攻擊者通過HTTP請求將資料傳送到伺服器,從而盜取會話的cookie。
盜取會話cookie之後,攻擊者不僅可以獲取使用者的資訊,還可以修改該cookie關聯的賬戶資訊。
django實現csrf_token認證
1.form表單實現csrf_token認證
直接寫上{% csrf_token %}
<form action=""> {% csrf_token %} <input type="text" name="username"> <input type="submit"> </form>
2.ajax實現csrf_token認證
方式1
在html裡,寫了個{% csrf token %},其實翻譯過來,就是生成了個input標籤
input標籤是這個樣子的:
<input type="hidden" name="csrfmiddlewaretoken" value="BzOzpsnD1zqiZMm3jp1TdW2knEI2BvxwEXrsJbZTIdqL1Kj6P7o4pN38sTn8K5ia">
我們在js中獲取屬性name為csrfmiddlewaretokan的那個input標籤的value的值
然後通過ajax中的data傳遞過去
// 方式1 <input type="text" name="username"> <button id="btn">確認</button> {% csrf_token %} <script src="{% static 'plugins/jquery.js' %}"></script> <script> var uname = $('#username').val(); // 方式1 // 通過input標籤的name屬性獲取csrfmiddlewaretoken的值 var token = $('[name="csrfmiddlewaretoken"]').val(); $.ajax({ url:'/ajax_login', type:'post', data:{uname:uname,csrfmiddlewaretoken:token} success:function (res) { alert(res) } }) </script>
方式2
這種方式和方式1差不多,只是在data中csrfmiddlewaretoken的值 變成了{{ csrf_token }}
在django中可以通過雙大括號取值
<input type="text" name="username"> <button id="btn">確認</button> {% csrf_token %} <script src="{% static 'plugins/jquery.js' %}"></script> <script> var uname = $('#username').val(); $.ajax({ url:'/ajax_login', type:'post', // 方式2 // 直接拿到csrfmiddlewaretoken中value屬性對應的值 data:{uname:uname,csrfmiddlewaretoken:'{{ csrf_token }}'}, success:function (res) { alert(res) } }) </script>
方式3
data裡不在寫csrfmiddlewaretoken,而是寫在ajax中的header裡
這種方法的csrf認證是寫在cookie裡的 cookie裡的csrf和input標籤裡value的csrf是不一樣的
<input type="text" name="username"> <button id="btn">確認</button> {% csrf_token %} <script src="{% static 'plugins/jquery.js' %}"></script> <script> var uname = $('#username').val(); $.ajax({ url:'/ajax_login', type:'post', data:{uname:uname}, headers:{ 'X-CSRFToken':$.cookie('csrftoken') // 這個csrftoken是cookie中的csrftoken,並非csrfmiddlewaretoken的值,兩者本身是同一個之,但是二者的加密方式不同,所以加密出來的結果不相同 }, success:function (res) { alert(res) } }) </script>
django實現檔案上傳
1.form表單實現檔案上傳
<form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} 使用者名稱:<input type="text" name="username" > <!-- type型別設定為file,multiple代表可以上傳多個檔案 --> 頭像:<input type="file" name="avatar" multiple> <input type="submit"> </form>
2.ajax實現檔案上傳
從html獲取資料,在js中獲取定義成變數
然後放到formdata中
在ajax中的data直接傳formdata即可,注意加processData和ContentType
使用者名稱:<input type="text" name="username" id="username"> 頭像:<input type="file" name="avatar" id="avatar"> <button id="ajax_btn">上傳</button> <script> $('#ajax_btn').click(function () { var uname = $('#username').val(); var file_obj = $('#avatar')[0].files[0]; // 檔案物件 var formdata = new FormData(); // 建立formdata物件,用來獲取表單資料,方便進行提交資料 formdata.append('username',uname); // 獲取input框輸入的使用者名稱 formdata.append('csrfmiddlewaretoken','{{ csrf_token }}'); // 獲取csrf_token值 formdata.append('avatar',file_obj); // 獲取使用者上傳的檔案物件 $.ajax({ url:'/login/', type:'post', data:formdata, processData: false , // 不處理資料 contentType: false, // 不設定內容型別 success:function (res) { console.log(res); } }) }) </script>
3.檔案上傳的views.py(form表單和ajax都用這套檢視函式)
通過request讀取在前端js定義好的file_obj
然後通過檔案物件.name 取出檔名 為接下來with open操作做準備
with open(檔名....)開啟檔案
for迴圈檔案物件 將檔案內容寫入其他地方
def login(request): if request.method == 'GET': return render(request, 'login.html') else: file_obj = request.FILES.get('avatar') name = file_obj.name with open(name, 'wb') as f: # 方式1 # for i in file_obj: # \r\n
# 方式2 # for i in file_obj.chunks(): # \r\n for i in file_obj.chunks(): # \r\n 讀取65536B f.write(i) return HttpResponse('ok')