Django的csrf认证

1、什么是csrf

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性;

可以这样来理解:
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,
比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 


举例子说明csrf攻击流程:

黑客做了和银行系统一样的钓鱼网站,但其实已经对内部信息做了篡改,用户在不知道的情况下打开了这个钓鱼网站,登录并且转账,
用户点击提交后,钓鱼网站就会向真正的银行系统接口提交用户的信息,银行系统并不知道这个信息是黑客提交的,就会进行转账操作;

或者黑客利用cookie来实施csrf攻击,比如你登录了一个真的银行网站,但你在没有退出登陆的情况下又点开了一个钓鱼网站,
这个钓鱼网站要求用户发一个转账请求,此时用户并不知情,就携带着cookie发了一个转账请求,银行系统同样不知道这个信息是黑客提交的,就会进行转账操作;


2、Django前端防止csrf攻击的方法

防止csrf攻击的策略:

当用户访问一个网站时,网站会返回一大串字符串,用户数据提交给服务器后,那串字符串也会一起提交,

网站会验证字符串的正确性,而且字符串是随时变化的,只要网页一刷新,字符串就会更新;

image


settings.py中 'django.middleware.csrf.CsrfViewMiddleware', 这个中间件不要注释掉;


方式一:在form表单中应用:

<form action="" method="post">
    {% csrf_token %}    <!--写上这一句即可-->
    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password"></p>
    <p><input type="submit"></p>
</form>


方式二:在ajax中应用,也就是手动获取到字符串的value值(同一个页面可以获取),django中name="csrfmiddlewaretoken"是固定的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h3>正常网站</h3>
<!--form表单验证csrf问题-->
<form action="" method="post">
    {% csrf_token %}
    <p>username: <input type="text" name="username"></p>
    <p>money: <input type="text" name="money"></p>
    <p>others: <input type="text" name="others"></p>
    <input type="submit">
</form>

<!--ajax表单验证csrf问题-->
<button>ajax</button>
</body>
<script>
    $('button').click(function () {
        $.ajax({
            url:'',
            type:'post',
            <!--ajax 方式-->
            data:{'name': 'jason', 'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()},
            success:function (data) {
                console.log(data)
            }
        })
    })
</script>
</html>


3、后端操作csrf

比如当全局开启csrf验证时,有某个页面不需要验证:
views.py

# 需要导入以下模块
from django.views.decorators.csrf import csrf_exempt, csrf_protect

# 不再检测(全站使用时)
@csrf_exempt
def csrf_token(request):#
    if request.method=='POST':
        print(request.POST)

        return HttpResponse('ok')
    return render(request,'csrf_token.html')


比如当全局禁用csrf验证时,有某个页面需要验证:

views.py

# 需要导入以下模块
from django.views.decorators.csrf import csrf_exempt, csrf_protect

# 检测(全站禁用时)
@csrf_protect
def csrf_token(request):#
    if request.method=='POST':
        print(request.POST)

        return HttpResponse('ok')
    return render(request,'csrf_token.html')


在CBV中使用:

# 先导模块
from django.utils.decorators import method_decorator

# 当全局禁用csrf时,也就是把那个中间件注释掉了,使用方法和CBV验证session时装饰器的用法一样(三种),  
https://www.cnblogs.com/weiyiming007/p/12401218.html


# 当全局启用csrf时,也就是把那个中间件没有注释掉,只能有下面两种方式,其实都是给dispatch加
@method_decorator(csrf_exempt,name='dispatch')  # 第一种 
class Index3(View):
    # @method_decorator(csrf_exempt)   # 第二种  
    def dispatch(self, request, *args, **kwargs):
        super().dispatch(request,*args,**kwargs)
posted @ 2020-03-04 17:08  米兰的小铁將  阅读(254)  评论(0编辑  收藏  举报