CSRF
即跨站请求攻击
跨站请求伪造csrf
钓鱼网站
本质搭建一个跟正常网站一模一样的页面
用户在该页面上完成转账功能
转账的请求确实是朝着正常网站的服务端提交
唯一不同的在于收款账户人不同
给用户书写form表单 对方账户的input没有name属性
你自己悄悄提前写好了一个具有默认的并且是隐藏的具有name属性的input
模拟钓鱼网站
form表单中csrf校验
<form action="" method="post">
{% csrf_token %}
old_password:<input type="text" name="old_password">
new_password:<input type="text" name="new_password">
<input type="submit">
</form>
AJAX csrf校验
第一种方式:自己手动获取
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
// 第一种方式 自己手动获取
data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
success:function (data) {
alert(data)
}
})
})
第二种方式:利用模板语法
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
// 第二种方式 利用模板语法
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
success:function (data) {
alert(data)
}
})
})
第三种方式:通用方式 引入外部js文件 官网提供的方式
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
##<script src="{% static 'myset.js' %}"></script>
success:function (data) {
alert(data)
}
})
})
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);
}
}
});
CSRF相关装饰器
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
@csrf_exempt # 不校验csrf
@csrf_protect # 校验
使用方法
在视图函数头上装
# @csrf_exempt # 不校验csrf
# @csrf_protect # 校验, 先注释中间件scrf
def transfer(srequest):
return HttpResponse('transfer')
CBV 只能在dispatch加
class MyHome(View):
@method_decorator(csrf_protect) # 第三种 类中所有的方法都装
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def post(self,request):
return HttpResponse('post')
def get(self,request):
return HttpResponse('get')