zoukankan      html  css  js  c++  java
  • Django学习---CSRF

    CSRF

     xss攻击:假设我们网站的评论里面允许用户写js的时候,每个人就会看到页面会执行这个js代码,有的是alert,不停的跳出弹框。这个还不算严重的,关键是如果js代码运行的结果不显示在页面上,偷偷的 把cookie发到他自己那去,这样攻击者就可以使用这个cookie登录网站。

    CSRF:

    1.原理:

    发送请求,第一次打开页面是get请求,请求数据,我们不仅把数据发送过去,而且还偷偷的发了一大堆字符串,这个字符串是加密的,只有自己可以反解。

    下一次我们提交数据的时候,要带着字符串来,这样才允许提交,不然的话,就报错,不允许提交数据。

    这个一般体现在哪呢?

    我们用django,如果我们往后台发送post的请求,我们没有把settings那个中间件注释的话,页面就直接出现403错误,比如:

    我现在把那个代码的注释去掉:

    我们打开我们的login页面,不管写什么点击提交,都会出现403错误:

     

    这个就是做了一层防护,get提交方式没有什么问题,一旦你以post方式提交,后台会先来去你发过来的请求里面去找一下那个随机字符串,这个是CSRF生成的字符串。

    那我们应该怎么解决这个问题呢?人家这里需要一个随机字符串,我们传一个就可以了。

    在django的内部,也支持生成这个随机的字符串:

    在form中我加上这个一个变量:csrf_token:

    我们在刷新一下:

    就多了一个字符串,这个字符串就是CSRF的token,以后再提交数据的时候就应该带这个字符串。

    但是我们这样在这里放一个字符串是没有用的,所以我们要用到下面的东西:

    我们在页面上没有看到那个字符串了,但是我们看一下生成的HTML代码:

    我们生成了一个隐藏的input,我们在提交数据的时候,后台就能够拿到这个数据了,拿到了就可以通过了。

    那如果我们没有这个CSRFtoken,会出现什么效果呢?

    假设我们先登录我们自己的网站,登录成功之后 ,我们先放着,我们打开其他的网站,提交表单登录,提交到我们的网站的网址上,如果我们没有这个token的话就直接提交了,但是如果有的话,其他网站的表单不可能有我们自己生成的token,就没有办法进行登录,这样就相当于做了一步防护的工作。

    上面是form表单提交数据,我们使用的是csrf_token,那如果是ajax提交我们应该怎么做呢?

    我们上面看到了在HTML中生成了一个隐藏的input,里面有一个字符串,其实在我们的cookie中也生成了一个:

    我们如果ajax请求,我们只需要拿到这个cookie的值,放到请求头里发过去就行了:

    $(function(){
    
                $('#btn').click(function(){
                    $.ajax({
                        url : '/login/',
                        type : 'POST', 
                        data : {'user':'root','passwd':'123'},
                        headers : {'X-CSRFtoken' : $.cookie('csrftoken')},
                        success : function (data) {
    
               },
           });
         });
    });

    这样就可以提交成功!

    当然如果我们下面有很多ajax操作,我们可以在ajaxSetup中添加之后,下面的ajax就不需要了:

    <!--在这个里面可以对所有的ajax做一个配置-->
                $.ajaxSetup({
                    beforeSend : function (xhr,settings) {<!--xhr:XMLHttpRequest 的对象,所有的ajax底层操作都是用这个,-->
                        xhr.setRequestHeader('X-CSRFtoken' , $.cookie('csrftoken'));
             }
    })

     在django中我们还支持:

    我们在MIDDLEWARE中把CSRF注释了,每个form提交的时候都要加上一个token,不加就无法进行验证,作用于全部。这个很明显是不合理的,因为有的时候我们说那个函数就不需要加CSRFtoken,会有这种需求。

    我们现在有一个需求,100form提交中有2个需要用到CSRFtoken验证,那怎么做呢?

    局部:

    • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

    注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

    CSRF只有在post提交的时候才起作用,如果用get请求,那不需要csrftoken,那我们可以在上面的ajaxsetup中做判断 

    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);
                    }
                }
            });
  • 相关阅读:
    OA
    Asp.net 将js文件打包进dll 方法
    ASP.NET编程中的十大技巧
    jquery 1.2.6 中文注释解析
    javascript 构造函数和方法
    asp.net命名空间
    .ascx和网页.aspx之间的交互方式
    windows 2003局域网共享设置
    javascript高级编程
    程序员需要具备的基本技能
  • 原文地址:https://www.cnblogs.com/charles8866/p/8838938.html
Copyright © 2011-2022 走看看