Django —— csrf 验证问题

关于 csrf 的基本了解

百度百科:CSRF(Cross-site request forgery)跨站请求伪造,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。通过伪装来自受信任用户的请求来利用受信任的网站。

简单来说就是攻击者盗用你的身份,以你的名义来发送恶意请求。比如说用户通过账号密码访问了网站A,A网站将一些cookie信息保存在浏览器中实现用户状态行为跟踪。这时用户又打开了B网站,B网站返回了一些恶意代码,并请求访问A。这样浏览器就会携带cookie以用户的权限访问A网站并执行代码。而在服务器看来,这些都是正常的用户操作。

在Django 中对csrf 的防范

Django中自带了防止csrf攻击的功能,但对于初学者来说可能不知道如何使用,并给自己带来些意外的麻烦。

例如:一个正常的表单提交操作却总是报错。

Django 中GET请求不需要csrf认证,post请求需要正确的认证才能得到正确的返回结果。
我们先处理一下对表单提交的 csrf 验证问题:一般在POST表单中加入{% csrf_token %}

<form method="POST" action="#">
{% csrf_token %}
	<input name='password' value='用户密码'>
</form>

加入了这句话后,再次提交post表单就不会出现问题了。
或者是另一个思路:禁用csrf
不过这样可能带来的危害你自己要想清楚了。
全局禁用:settings文件中找到关于csrf的中间件,直接注释。对于需要保护的视图加装饰器@csrf_protect。
针对性禁用:在表单提交的对应视图函数上加上一个装饰器 @csrf_exempt
关于csrf的装饰器官方文档:https://docs.djangoproject.com/en/2.2/ref/csrf/#module-django.views.decorators.csrf
对视图类使用装饰器:https://docs.djangoproject.com/en/2.2/topics/class-based-views/intro/#decorating-the-class

------------------------------------------------------------------
{% csrf_token %} 实际上是一个模板语法,将项目的token值写入到前端页面的表单中,这个值在建django项目时就已经自动生成,可以在setting中看到。
--------------------------------------------------------------------

下面再看一下Ajax调用时的处理方式

使用ajax与有开启csrf验证的视图进行交互时,需要确保ajax中能够获取到csrf token值
一 从当前html页面中获取token值(cookie也同时拥有token),如果是前后端分离,是没有这个的
二 如果从session 中获取 settings设置CSRF_USE_SESSIONS=True(token存储在session而不是cookie中)
三 如果从cookie 中获取 settings设置CSRF_COOKIE_HTTPONLY=False(默认)

Django提供了一个强制设置cookie的视图装饰器: ensure_csrf_cookie。

从cookie中获取token
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

// 通过使用JavaScript Cookie库替换以上代码可以简化getCookie:
// var csrftoken = Cookies.get('csrftoken');
从html中获取

如果csrf使用了session模式或者是禁止了cookie模式,需要从html中获取csrf token

<script type="text/javascript">
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
// 如果是使用django模版的页面
// var csrftoken = '{% csrf_token %}'
</script>
在data中添加token发送
// 每个ajax中都需要传递csrfmiddlewaretoken
$.ajax({
    url: ,url
    type: "POST",
    data: {
        "username": username,
        "password": password,
        // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data总
        "csrfmiddlewaretoken": csrftoken
    },
    success: function(data){
        console.log(data);
    }
})
在请求头上添加token发送

这样写可以不必为每个ajax的data中添加csrf token

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);
        }
    }
});
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值