django之CSFR

作者: print("") 分类: python 发布时间: 2018-08-02 23:33

django之CSFR

CSRF是什么?

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,

通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,

XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比

,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

django CSRF 

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

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

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

默认django的CSRF 是开启的 在settings中

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',  
]

django 认为用户提交的数据都是不安全的,所以会利用一个认证机制来防御这种攻击的方式。

首先我们新建一个页面如下:

urlpatterns = [
    path('/',views.login),
    path('admin/', admin.site.urls),
    url(r'^login/',views.login),
]

views中

def login(request):
    if request.method=='GET':
        return render(request,'lgoin.html')
    elif request.method=="POST":
        user=request.POST.get('user')
        pwd=request.POST.get('pwd')
        if user=='root' and pwd=='123':
            request.session['username']=user
            request.session['is_login']=True
            if request.POST.get('rmb',None)=='1':
                # 超时时间
                request.session.set_expiry(10)
            return redirect('/index/')
        else:
            return render(request, 'lgoin.html')

在login.html 中如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/login/" method="POST">

        <input type="text" name="user">
        <input type="password" name="pwd">
       
        <input type="submit"  value="登陆" />
        <input id="btn" type="button" value="按钮" />
    </form>
</body>
</html>

提交访问一下是一个403页面

那么怎么去做一个安全的页面呢?

打开网络中。发现cookies中有 CSRFtoken 这个东西。那么这个东西是怎么来的

那么这个东西是怎么来的。首先说下原理。当get请求服务器的之后,服务器会随机发一个字符串给你,存在cookies 中。 

就是为了做一个认证的方式,GET请求的时候是正常的。只有POST请求的时候发送数据服务端才会做认证

现在我们是FROM提交的。那么提交的时候一定需要是带有这个token的,才能提交成功。如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/login/" method="POST">
        {% csrf_token %}
        <input type="text" name="user">
        <input type="password" name="pwd">
        <input type="checkbox" name="rmb" value="1">10秒免登陆
        <input type="submit"  value="登陆" />
        <input id="btn" type="button" value="按钮" />
    </form>
</body>
</html>

加入一个{{% csft_token %}}

再次提交一下:

看一下cookies 

这边已经成功了。

那么如果发起ajax 怎么去处理呢。

HTML如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/login/" method="POST">
        {% csrf_token %}
        <input type="text" name="user">
        <input type="password" name="pwd">
        <input type="checkbox" name="rmb" value="1">10秒免登陆
        <input type="submit"  value="登陆" />
        <input id="btn" type="button" value="按钮" />
    </form>


<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
    $(function () {
        $.ajaxSetup({
            beforeSend:function (xhr,settings) {
              xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken'));
            }
        });




        var csrftoken=$.cookie('csrftoken');
        $('#btn').click(function () {
            $.ajax({
                url:'/login/',
                type:'POST',
                data:{ 'user':'root','pwd':'123' },
                success:function (arg) {

                }


            })
        })
    })

</script>
</body>
</html>

点击

成功提交了ajax请求。

总结:

1. from 提交

{% csrf_token %}

2. ajax提交

 $(function () {
        $.ajaxSetup({
            beforeSend:function (xhr,settings) {
              xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken'));
            }
        });




        var csrftoken=$.cookie('csrftoken');
        $('#btn').click(function () {
            $.ajax({
                url:'/login/',
                type:'POST',
                data:{ 'user':'root','pwd':'123' },
                success:function (arg) {

                }


            })
        })
    })

csrf_protect和csrf_exempt 应用

如果说你需要单个views 不设置csrf如下:

例如index

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

@csrf_exempt
def index(request):
    # 获取当前用户的随机字符串
    # 根据随机字符串获取对应的信息
    #
    if request.session.get('is_login',None):
        return render(request,'index.html',{'user':request.session['username']})
    else:
        return HttpResponse('<a href="/login">登陆</a>')

如果需要改成 csrf_protect 

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

一条评论
  • len

    2019年12月17日 下午5:33

    应该是form提交,你好像2个地方写成from提交了。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注