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>


posted on 2019-02-27 18:41  花豆豆  阅读(245)  评论(0编辑  收藏  举报