CSRF
跨站請求偽造
CSRF全稱為Cross-site request forgery,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。
CSRF攻擊:攻擊者盜用了你的身份,以你的名義發送惡意請求。CSRF能夠做的事情包括:以你名義發送郵件,發消息,盜取你的賬號,甚至於購買商品,虛擬貨幣轉賬......造成的問題包括:個人隱私泄露以及財產安全。
CsrfViewMiddleware的作用:
在render返回頁面的時候,在頁面中塞了一個隱藏的input標簽;當你提交POST數據的時候,它幫你做校驗,如果校驗不通過就拒絕這次請求
跨站請求偽造csrf :
1.網站的搭建 :
寫一個跟正規網站一模一樣的頁面;用戶輸入用戶名 密碼 對 方賬戶 轉賬金額提交,請求確實是朝銀行的接口發送的 錢也扣了
但是對方賬戶變了 變成了釣魚網站自己提前設置好的賬戶
2,釣魚網站功能的實現 :
填寫form表單的時候 讓用戶填寫的對方賬戶input並沒有name屬性,是你自己在內部偷偷隱藏了一個具有name屬性的input框,並且value值是你自己的賬戶 然后將該標簽隱藏了
解決跨站偽造問題:
解決跨站問題 :
1.讓服務端只處理本網站發送的post請求
2.識別判斷當前請求是否是本網張發出的
網站在返回給用戶一個form表單的時候 會自動在該表單隱藏一個input框;框的value是一個隨機字符串 但是網站能夠記住每一個瀏覽器發送的隨機字符串
from 表單發送 POST請求:
<form action="" method="post">
{% csrf_token %}
<p>username:<input type="text" name="username"></p>
<p>target_account:<input type="text" name="target_user"></p>
<p>money:<input type="text" name="money"></p>
<input type="submit">
</form>
ajax 發送 POST請求:
先在頁面任意的位置上書寫
{ % csrf_token %}
1.方式1
通過標簽查找獲取隨機字符串添加到data自定義對象即可
data: {'username': 'jason', 'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
2.方式2
data: {'username': 'jason', 'csrfmiddlewaretoken': '{{ csrf_token }}'},
3.方式3
直接興建js文件拷貝代碼,導入即可
csrf.js文件
csrf 相關的裝飾器:
#1. FBV模型:
from django.views.decorators.csrf import csrf_exempt,csrf_protect
# @csrf_exempt # 不校驗 csrf(中間件)
def index(request):
return HttpResponse('index')
# @csrf_protect # 校驗
def login(request):
return HttpResponse('login')
# 2. CBV模型:
from django.utils.decorators import method_decorator
1.# @method_decorator(csrf_exempt,name='xxx') # csrf_exempt 不支持裝飾
2.@method_decorator(csrf_exempt,name='dispatch') # csrf_exempt 支持裝飾 dispatch
class HomeView(View):
# @method_decorator(csrf_exempt) # 支持裝飾
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
# @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持該方法
def post(self,request):
return HttpResponse('OK')
總結 : csrf_exempt這個裝飾器只能給dispatch裝才能生效
csrf_protect方式全都可以跟普通的裝飾器裝飾CBV一致
csrf.js文件:
# ajax csrf.js文件
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) {
// 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);
}
}
});