zoukankan      html  css  js  c++  java
  • Django——CSRF_TOKEN跨站请求伪造 & session版登录认证

    1.知识储备

    1 django解决了csrf攻击,中间件: 
     django.middleware.csrf.CsrfViewMiddleware
    '''
    内部实现:
    向浏览器发POST请求时,每次请求都会在模板里隐藏content ,会默认返回一个csrf  k:v 的值(k时csrf,v是随机字符串 可以在process_request里面取出,再根据k取出v进行校验),这个值会隐藏在页面中,
    下次发请求时一定要带着这个隐藏的字符串,如果不想携带就报403 Forbidden禁止访问(黑客拿不到这个随机字符串,并且串有失效时间防止黑客破解拿出)
    '''

    2 后期中间件不能注释,每次发送post请求,都需要携带csrf_token随机字符串 -form表单提交 -在form表单中 {% csrf_token%}  '''
       {{csrf_token}}  #变量,不能用这个
      {% csrf_token %} #标签,使用这个
        '''
        -ajax提交(如何携带)
        方式一:放到data中 (***推荐)
         $.ajax({
                url: '/csrf_test/',
                method: 'post',
                data: {'name': $('[name="name"]').val(),
                    'password': $('[name="password"]').val(),
                    'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()
                },
                success: function (data) {
                    console.log('成功了')
                    console.log(data)
    
                },
                error: function (data) {
                    console.log('xxxxx')
                    console.log(data)
    
                }
            })
            方式二:放到data中
            'csrfmiddlewaretoken':'{{ csrf_token }}'
            方式三:放到头中
                headers:{'X-CSRFToken':'{{csrf_token}}'},
            
            
     # jquery.cookie.js
        -在浏览器中对cookie进行增,删,查,改
        -前后端分离(js操作cookie)
        
        
        
    # 全局使用,局部禁csrf
        -在视图函数上加装饰器
        from django.views.decorators.csrf import csrf_exempt,csrf_protect
    # 全局启用,局部禁用(中间件不能注释,这个视图函数,已经没有csrf校验了)
     @csrf_exempt #加上这个装饰器
     def csrf_test(request):
         if request.method=='GET':
             return render(request,'csrf_test.html')
         else:
             name=request.POST.get('name')
             password=request.POST.get('password')
             print(name)
             print(password)
             return HttpResponse('登录成功')
    
    # 全局禁用,局部使用csrf
    @csrf_protect  #加上这个装饰器
    def csrf_test(request):
        if request.method=='GET':
            return render(request,'csrf_test.html')
        else:
            name=request.POST.get('name')
            password=request.POST.get('password')
            print(name)
            print(password)
            return HttpResponse('登录成功')
    
    
    # 古怪的使用方式,在urls.py中
    path('csrf_test/', csrf_exempt(views.csrf_test))

    2.模拟银行转账中出现的csrf攻击

    settings.py

    MIDDLEWARE = [
        ...
        'django.middleware.csrf.CsrfViewMiddleware',
        ...
    ]

    urls.py

    from django.urls import path
    from app01 import views
    from django.views.decorators.csrf import csrf_exempt
    
    urlpatterns = [
         
           path('', views.index),
           path('transfer/', views.transfer),
           path('csrf_test/', views.csrf_test),
    ]

    views.py

    from django.shortcuts import render,HttpResponse,redirect
    
    def login_auth(func):
        def inner(request, *args, **kwargs):
            # 登录校验
            name = request.session.get('name')
            if name:
                res = func(request, *args, **kwargs)
                return res
            else:
                path = request.get_full_path()
                return redirect('/login/?returnUrl=%s' % path)
    
        return inner
    
    ### session版登录
    def login(request):
        if request.method == 'GET':
    
            return render(request, 'login.html')
        else:
            name = request.POST.get('name')
            password = request.POST.get('password')
            if name == 'lqz' and password == '123':
                # 写入session
                # 登录成功,重定向
                request.session['name']=name
                path = request.GET.get('returnUrl')
                if path:
                    obj = redirect(path)
                else:
                    obj = redirect('/index/')
    
                return obj
            else:
                return HttpResponse('用户名或密码错误')
    
    @login_auth
    def index(request):
        return render(request,'index.html')
    
    @login_auth
    def transfer(request):
        # /transfer/?from=lqz&to=egon&total=100
        f=request.GET.get('from')
        t=request.GET.get('to')
        total=request.GET.get('total')
        print('转账成功')
        return HttpResponse('转账成功')
    
    
    def csrf_test(request):
        if request.method=='GET':
            return render(request,'csrf_test.html')
        else:
            name=request.POST.get('name')
            password=request.POST.get('password')
            print(name)
            print(password)
            return HttpResponse('登录成功')

    csrf_test.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
        <title>Title</title>
    </head>
    <body>
    
    {% csrf_token %}
    
    <form action="" method="post">
     <p>用户名<input type="text" name="name"></p>
    <p>密码<input type="password" name="password"></p>
    <p><input type="submit" value="提交" id="submit"></p>
    </form>
    </body> </html>

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>银行正版网站</title>
    </head>
    <body>
    
    <a href="/transfer/?from=lqz&to=egon&total=100">点我,给egon转100块钱</a>
    
    </body>
    </html>
  • 相关阅读:
    openstack trove实例状态转换条件--Mitaka版本
    trove module使用说明
    openstack trove mongodb配置项
    openstack trove weekly meeting时间即将更改
    openstack trove redis配置项
    trove database功能总结
    openstack trove 数据库镜像构建列表
    openstack trove主要贡献公司-Tesora被Stratoscale收购
    openstack trove,使pylint忽略错误
    十件你需要知道的事,关于openstack-trove(翻译)
  • 原文地址:https://www.cnblogs.com/guojieying/p/13863481.html
Copyright © 2011-2022 走看看