Django中 前端post方式ajax传json数据 通过csrf机制

介绍一下csrf
​ csrf是跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。

​ 漏洞的成因就是网站的cookie在浏览器中不会过期,只要不关闭浏览器或者退出登录,那以后只要是访问这个网站,都会默认你已经登录的状态。而在这个期间,攻击者发送了构造好的csrf脚本或包含csrf脚本的链接,可能会执行一些用户不想做的功能(比如是添加账号等)。这个操作不是用户真正想要执行的。

问题描述

1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4.网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

 

解决方式大致分为两类:

一种是取消csrf防御机制类

 

  在模块上添加@csrf_exempt

 

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def  login(request):
    if request.method == 'POST' :
             print('可以直接post')

            return render(request,'login.html')
               

  

 

  全局设置过滤csrf

就是setting配置文件里把’django.middleware.csrf.CsrfViewMiddleware’,删掉

 

 

不取消csrf防御机制类

  1. 前台用{% csrf_token %}传到后台

方法前端用ajax时,请求头增加一句

 headers:{'X-CSRFToken': csrf},

  

 

 

正常不用ajax的post传输是在form表单里添加{% csrf_token %},添加之后运行时template会自动把它转换成
<input type="hidden" name="csrfmiddlewaretoken" value="aqYPU74oA3swVzZMOPlEdh4Tle2cM4hI8kvuwKL1sdBFgWH98sqzb9svOPv1DmMb">

所以用ajax传的时候可以直接用属性选择器把这个标签的value值获取传到后台即可解决
代码展示:前提是在form表单里添加{% csrf_token %}

  

	//ajax部分:
    	var loginUsername = $('#loginUsername').val();
        var loginPassword = $('#loginPassword').val();
        //主要是这条-----------------------------------------------------------------------
        var csrf = $("input[name='csrfmiddlewaretoken']").val();
        
        var params = {};
        params.loginUsername = loginUsername;
        params.loginPassword = loginPassword;
        var loginLoadIndex = layer.load(2);
        $('#loginBtn').val("正在登录...");
        $.ajax({
            type:'post',
            url:window.location.protocol+'//'+window.location.host+'/user/login/',
            dataType:'html',
            //还有这个-------------------------------------------------
            headers:{'X-CSRFToken': csrf},
            
            data:JSON.stringify(params),//这是将数据json格式转换
            contentType:'application/json',
            success:function (data) {
                layer.close(loginLoadIndex);
                var jsonData = JSON.parse(data);
                if (jsonData.code == '999'){
                    window.location.href = '/showdata/index/';
                }
            },
            error:function () {
                layer.close(loginLoadIndex);
                $('#loginBtn').val("登录");
            }
        });
     view部分:
    	#用这条接收前台传过来的json数据
    	request_data = request.body
        print(request_data)
        request_dict = json.loads(request_data.decode('utf-8'))
        username = request_dict.get('loginUsername')
        password = request_dict.get('loginPassword')

  

 

posted @ 2021-05-17 16:54  JIMfan  阅读(273)  评论(0)    收藏  举报