1. CSRF是基于中间件的process_view方法实现的
2. CSRF(Cross-site request forgery)又称为跨站请求伪造,也被称为"One Click Attack"或者"Session Riding",在Django中被称为CSRF,在Tornado中被称为XSRF,是一种对网站的恶意利用。
3. https://baike.baidu.com/item/CSRF/2735433 详细介绍
4. 在Django中,如果有需要通过form表单进行数据提交的话,就需要在网站页面form表单里面添加{% csrf_token %},例如:
<form class="navbar-form navbar-left">
<div class="form-group">
{% csrf_token %} 添加
<input type="text" class="form-control" name="search" id="search" placeholder="请输入id/用户名/手机号">
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
使用csrf后,会自动生成一个随机字符串,在用户提交数据后,这个随机字符串也一并会被提交,并和后端的进行比较,如果一致,则执行成功,如果不一样,则执行失败
5. 如果在全栈都使用csrf的时候,要对部分的函数禁用csrf的话,就需要对这部分的函数加上一个装饰器:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def delete(request):
"""
:param request: 删除用户
:return:
"""
if request.method == 'POST':
del_user = request.POST.get('username')
models.User.objects.filter(user=del_user).delete()
return redirect('/backstage/')
return render(request,'delete.html')
加上这个装饰器后,请求到这个函数的时候,就不会在对这个函数进行csrf检测了
6. 局部使用csrf,当把settings中的csrf注释掉以后,如果有函数需要使用csrf的话,则就需要导入模块csrf_protect
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def delete(request):
"""
:param request: 删除用户
:return:
"""
if request.method == 'POST':
del_user = request.POST.get('username')
models.User.objects.filter(user=del_user).delete()
return redirect('/backstage/')
return render(request,'delete.html')
7. 如果再CBV中使用csrf的话和在FBV中是不一样的,必须是给这个类统一加上一个装饰器,比如:
from django.views import View
from django.views.decorators.csrf import csrf_protect,csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_protect,name='post') 只能是调用method_decorator来添加装饰器,不过可以在里面指定一个name,如果只想给post方法使用csrf的话,则直接name='post'就可以,不能直接在方法上面加
class Foo(View):
def get(self):
pass
def post(self):
pass
PS:在django中,如果想使用装饰器的话,上面的例子则是一个办法,还有另外的方法是直接在方法名上加@method_decorator(wrapper),比如:
from django.views import View
from django.utils.decorators import method_decorator
class Foo(View):
@method_decorator(wrapper) 也可以在方法名上面加,和上面的使用方法一样
def get(self):
pass
def post(self):
pass
只有在使用csrf的时候只能在类名上面加装饰器,使用普通装饰器的时候则不用遵循这个规则
8. Ajax提交数据时候,携带CSRF:
a. 放置在data中携带
<form method="POST" action="/csrf1.html">
{% csrf_token %}
<input id="user" type="text" name="user" />
<input type="submit" value="提交"/>
<a onclick="submitForm();">Ajax提交</a>
</form>
<script src="/static/jquery-1.12.4.js"></script>
<script>
function submitForm(){
var csrf = $('input[name="csrfmiddlewaretoken"]').val();
var user = $('#user').val();
$.ajax({
url: '/csrf1.html',
type: 'POST',
data: { "user":user,'csrfmiddlewaretoken': csrf},
success:function(arg){
console.log(arg);
}
})
}
</script>
b. 放在请求头中
<form method="POST" action="/csrf1.html">
{% csrf_token %}
<input id="user" type="text" name="user" />
<input type="submit" value="提交"/>
<a onclick="submitForm();">Ajax提交</a>
</form>
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
function submitForm(){
var token = $.cookie('csrftoken');
var user = $('#user').val();
$.ajax({
url: '/csrf1.html',
type: 'POST',
headers:{'X-CSRFToken': token},
data: { "user":user},
success:function(arg){
console.log(arg);
}
})
}
</script>
浙公网安备 33010602011771号