Django与CSRF 、AJAX
CSRF(Cross-site request forgery)跨站請求偽造,是一種常見的網絡攻擊手段,具體內容和含義請大家自行百度。
Django為我們提供了防范CSRF攻擊的機制。
一、基本使用
默認情況下,使用django-admin startproject xxx命令創建工程時,CSRF防御機制就已經開啟了。如果沒有開啟,請在MIDDLEWARE設置中添加'django.middleware.csrf.CsrfViewMiddleware'。
對于GET請求,一般來說沒有這個問題,CSRF通常是針對POST方法的!
在含有POST表單的模板中,需要在其<form>表單元素內部添加csrf_token標簽,如下所示:
<form action="" method="post"> {% csrf_token %} .... </form>這樣,當表單數據通過POST方法,發送到后臺服務器的時候,除了正常的表單數據外,還會攜帶一個CSRF令牌隨機字符串,用于進行csrf驗證。其實沒有多么麻煩和復雜,對么?如果表單中沒有攜帶這個csrf令牌,你將會獲得一枚403獎章。
額外提示:對于初學者,要明白一件事情,就是我們上面講的都是Django項目自己內部的事務,不涉及與外界的關系。例如,你不能把上面那個表單發往百度,百度會懵逼的,你這發的啥?其次,那樣也不安全,可能引起CSRF信息泄露而導致自己的站點出現漏洞。
二、 AJAX
我們知道,在前端的世界,有一種叫做AJAX的東西,也就是“Asynchronous Javascript And XML”(異步 JavaScript 和 XML),經常被用來在不刷新頁面的情況下,提交和請求數據。如果我們的Django服務器接收的是一個通過AJAX發送過來的POST請求的話,那么將很麻煩。
為什么?因為AJAX中,沒有辦法像form表單中那樣攜帶{% csrf_token %}令牌。
那怎么辦呢?
好辦!在你的前端模版的JavaScript代碼處,添加下面的代碼:
// using jQuery function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken'); function csrfSafeMethod(method) { // 這些HTTP方法不要求CSRF包含 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });上面代碼的作用就是讓你的ajax的POST方法帶上CSRF需要的令牌,它依賴Jquery庫,必須提前加載Jquery。這是Django官方提供的解決方案哦,^-^。
三、裝飾器
1. 單獨指定csrf驗證需要
有時候,我們在全站上關閉了CSRF功能,但是希望某些視圖還有CSRF防御,那怎么辦呢?
Django為我們提供了一個csrf_protect(view)裝飾器,使用起來非常方便,如下所示:
from django.views.decorators.csrf import csrf_protect from django.shortcuts import render @csrf_protect def my_view(request): c = {} # ... return render(request, "a_template.html", c)現在,雖然全站關掉了csrf,但是my_view視圖依然需要進行csrf驗證。
2. 單獨指定忽略csrf驗證
有正就有反。在全站開啟CSRF機制的時候,有些視圖我們并不想開啟這個功能。比如,有另外一臺機器通過requests庫,模擬HTTP通信,以POST請求向我們的Django主機服務器發送過來了一段保密數據。它無法攜帶CSRF令牌,必然會被403。
這怎么辦呢?
在接收這個POST請求的視圖上為CSRF開道口子,不進行驗證。這就需要使用Django為我們提供的csrf_exempt(view)裝飾器了,下面是使用范例:
from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponse @csrf_exempt def my_view(request): return HttpResponse('Hello world')這下POST數據是沒問題了,但是又帶來了新的安全問題,需要你自己處理。
3. 確保csrf令牌被設置
Django還提供了一個裝飾器,確保被裝飾的視圖在返回頁面時同時將csrf令牌一起返回。
這個裝飾器是:ensure_csrf_cookie(view),其使用方法和上面的一樣:
from django.views.decorators.csrf import ensure_csrf_cookie from django.http import HttpResponse @ensure_csrf_cookie def my_view(request): return HttpResponse('Hello world')4. requires_csrf_token(view)
這個裝飾器類似csrf_protect,一樣要進行csrf驗證,但是它不會拒絕發送過來的請求。
from django.views.decorators.csrf import requires_csrf_token from django.shortcuts import render @requires_csrf_token def my_view(request): c = {} # ... return render(request, "a_template.html", c)轉載于:https://www.cnblogs.com/dontgiveup/p/9801730.html
總結
以上是生活随笔為你收集整理的Django与CSRF 、AJAX的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django的中间件
- 下一篇: windows 10 扩大C盘空间