Django的CSRF防禦機制

什麼是CSRF?

  CSRF(Cross-site request forgery), 中文名稱:跨站請求僞造,也被稱爲:one click attack/session riding,縮寫爲:CSRF/XSRFjavascript

CSRF攻擊過程

  

  從上圖能夠看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:html

    一、登錄受信任的網站A,並在本地客戶端(瀏覽器)產生Cookie;前端

    二、在不退出A的狀況下(準確的說是在訪問A網站產生的Cookie不過時的狀況下),訪問危險網站B;java

Django 的CSRF防護機制

  注:django框架只對來自客戶端的post請求進行CSRF防護,get請求django默認是合法的請求jquery

  django 在第一次響應來自某個客戶端的請求時,會在服務器端隨機產生一個token,把這個token放在cookie裏,而後每次ajax

  post請求都會攜帶這個token,這樣就能避免CSRF攻擊。django

具體的實現方法

  django經過中間件 django.middleware.csrf.CsrfViewMiddleware 來防止跨站請求僞造,而對於django中設置防止後端

跨站請求僞造功能分爲全局設置和局部設置瀏覽器

全局:服務器

  中間件 django.middleware.csrf.CsrfViewMiddleware 

  注:中間件會在全局上進行防止post請求的CSRF攻擊

局部:

  一、@csrf_protect,爲當前View視圖函數強制設置防CSRF攻擊,即使settings中沒有設置全局的中間件

  二、@csrf_exempt,取消當前View視圖函數防止CSRF攻擊,即使settings中設置了全局中間件(也能夠在url中取消csrf防禦)

  注:from django.views.decorators.csrf import csrf_exempt, csrf_protect

具體應用

一、在from表單中附加csrftoken

前端
{% csrf_token %}
後端
view視圖函數中設置返回值
#在渲染模塊時,使用 RequestContext。RequestContext 會處理模板中{% csrf_token %} 這個 tag,從而自動爲表單添加一個名爲 csrfmiddlewaretoken 的 input標籤
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request)) 
或者
#使用render則會自動生成,不用ReqestContext
return render(request, 'xxx.html', data) 
 

 二、Ajax發送post請求

前端:

  在進行post提交時,獲取Cookie當中的csrftoken並在request請求中添加X-CSRFToken請求頭,請求頭的數據就是csrftoken。

  經過$.ajaxSetup方法設置AJAX請求的默認參數選項,在每次ajax的POST請求時,添加X-CSRFToken請求頭

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
  <input type="button" onclick="Do();" value="Do it"/> <script src="/static/plugin/jquery/jquery-1.8.0.js"></script> <script src="/static/plugin/jquery/jquery.cookie.js"></script> <script type="text/javascript"> var csrftoken = $.cookie('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); function Do(){ $.ajax({ url:"/app01/test/", data:{id:1}, type:'POST', success:function(data){ console.log(data); } }); } </script> </body> </html>

 

後端

1.表單中添加{%csrf_token%}這個模板標籤

<form id="comment_form" action="#"></form> {% csrf_token %} 就是這個 <p>姓名: <input type="text" name="useranme" id="username"></p>
<p>內容: <textarea name="content" id="content" rows="5" cols="30"></textarea></p>
<p><input type="button", id="send" value="提交"></p>

2.ensure_csrf_cookie裝飾器。

from django.shortcuts import render from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def ajax_demo(request): return render(request, 'ajax_demo.html')
相關文章
相關標籤/搜索