DjangoCSRF原理

1.CSRF介绍

csrf,跨站请求伪造,也被称为"One Click Attack"或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

为了防止这种现象,需要在Ajax提交时,为form表单添加一个随机字符串,以避免被恶意篡改。Django中为了实现这一功能,可以通过在settings文件中,使用以下中间件:

  django.middleware.csrf.CsrfViewMiddleware

以上方法是在全局设置,在局部设置时:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_protect:装饰某个函数,为该函数强制设置防跨站请求伪造功能,即便在settings文件中没有设置全局中间件。
@csrf_exempt:装饰某个函数,取消该函数防跨站请求伪造功能,即便在settings文件中设置了全局中间件。

2.使用例子

在views.py文件中写如下:

@csrf_protect
def login(request):
    from django.conf import settings
    print(settings.CSRF_HEADER_NAME)  #HTTP_X_CSRFTOKEN
    #X-CSRFtoken  实际
    if request.method=="GET":
        return render(request,"c_login.html")
    elif request.method=="POST":
        u=request.POST.get("username")
        pwd=request.POST.get("pwd")
        print(u,pwd)
        if u in user_info and pwd==user_info[u]["pwd"]:
            request.session["username"]=u
            request.session["is_login"]=True
            if request.POST.get("no_login",None)=="1":  #状态在前端被选中
                request.session.set_expiry(10)      #人为设置超时时间为10秒钟
                print("10秒后,超时")
            return  redirect('/cook/s_index/')
        else:
            return render(request,"c_login.html")

在c_login文件中写如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<div>
    <form action="/cook/login/" method="post">

<input type="text" name="username" placeholder="用户名">
        {% csrf_token %}
<input  type="password" style="display: none;" >
<input  type="password" name="pwd" placeholder="密码" autocomplete="new_password" >
<input type="checkbox" name="no_login" value="1"/>10秒内免登录
<input type="submit"  value="提交" id="btn2">
<input type="button"  value="测试提交" id="btn1">
        </form>
    </div>
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script  type="text/javascript">
    $(function(){
        $.ajaxSetup({
            beforeSend:function(xhr,settings){
                {#xhr  是xmlhttpRequest对象  xhr.open() xhr.send()  在发送前统一做配置#}
                xhr.setRequestHeader("X-CSRFtoken",$.cookie('csrftoken'));
            }
        });

        $('#btn1').click(function () {
            $.ajax({
                url:'/cook/login',
                method:'GET',
                data:{"username":'A','pwd':'123456'},
                {#headers:{"x-CSRFtoken":$.cookie('csrftoken')},#}
                success:function (arg) {
                }
            })
        })
    })
</script>
</body>
</html>

为了实现某些附加功能,如请求方式为get、head、option、trace的ajax请求不做CSRF验证,代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    {% csrf_token %}
  
    <input type="button" onclick="Do();"  value="Do it"/>
  
    <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
    <script src="/static/plugin/jquery/jquery.cookie.js"></script>
    <script type="text/javascript">
        var csrftoken = $.cookie('csrftoken');
  
        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);
                }
            }
        });
        function Do(){
  
            $.ajax({
                url:"/app01/test/",
                data:{id:1},
                type:'POST',
                success:function(data){
                    console.log(data);
                }
            });
  
        }
    </script>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

theskylife

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值