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>