day75

 1 django的session原理流程
 2 自定义中间件
 3 process_request,process_response,process_view,process_exception
 4 CSRF_TOKEN跨站请求伪造

https://www.cnblogs.com/liuqingzheng/articles/9509739.html

# 昨日回顾

```python
1 django中cookie的使用
   -增 obj.set_cookie(key,value,max_age)
    -删 obj.delete_cookie(key)
    -查 request.COOKIE.get(key)
    -改 obj.set_cookie(key,value,max_age)
2 django中session的使用(迁移数据库)
    -增 request.session['key']=value
    -删 del request.session['key']
    -全部删除 request.session.flush():cookie和数据库都删除   request.session.delete()只删数据库
    -查 request.session['key']
    -改 request.session['key']=value
    
    -超时时间
    
3 cbv加装饰器
    -第一种:加在类上
        from django.utils.decorators import method_decorator
        @method_decorator(login_auth,name='get')
        class UserList(views.View):
            pass
    -第二种:加在方法上
        from django.utils.decorators import method_decorator
       
        class UserList(views.View):
            @method_decorator(login_auth)
            def get(self):
                pass
```





# 今日内容

## 1 django的session原理流程




## 2 自定义中间件

```python
1 自定义步骤:
    -写一个类,继承MiddlewareMixin
    -里面写方法process_request(请求来了,一定会触发它的执行)
    -在setting中配置(注意,放在前和放在后)
        MIDDLEWARE = [
            ...
            'app01.mymiddle.MyMiddleware1',
            ...
        ]
```



## 3process_request,process_response,process_view,process_exception

```python
1 process_request(request对象)
2 process_response(request对象,response对象)
3 多个中间件,执行顺序是什么?
    -请求来的时候从上往下执行:process_request
    -请求走的时候,从下往上执行:process_response
        
        
4 process_request可以干什么?
    -写一个中间件,不管前端用什么编码格式,在requset.data中都有post的数据
    -频率限制(限制某个ip地址,一分钟只能访问5次)
    -登录认证(只要没登录,重定向到login路径)、
    -记录用户访问日志(ip,时间,访问路径)
    
5 process_response可以干什么?内部有response对象
    -统一给所有(某几个路径)加cookie
    -统一给所有(某几个路径)加响应头
    
    
    
6 process_view 路由匹配成功和视图函数执行之前执行(callback就是视图函数)
    def process_view(self, request, callback, callback_args, callback_kwargs):
            # print(callback)
            # print(callback_args)
            # print(callback_kwargs)
            #
            res=callback(request)
            #
            print("中间件1的process_view")
            return res
7 process_exception 视图函数出错,会执行它(全局异常捕获)(记录日志,哪个ip地址,访问哪个路径,出的错)
    # 全局异常捕获,返回4开头的
    def process_exception(self, request, exception):
        print(exception)
        return render(request,'error.html')
```



## 4 CSRF_TOKEN跨站请求伪造

```python
1 跨站请求伪造
2 代码演示


3 django解决了csrf攻击,中间件:django.middleware.csrf.CsrfViewMiddleware


4 后期中间件不能注释,每次发送post请求,都需要携带csrf_token随机字符串
    -form表单提交 
        -在form表单中 {% 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))
```
# app01_middleware.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse


# process_view
class MyMiddleware1(MiddlewareMixin):
    # 所有的请求来了,都会走到process_request
    def process_request(self, request):            # request就是当次请求的request对象
        print('请求来了1')
        # print(request.session)
        # 可以返回,必须返回HttpResponse的对象
        # return HttpResponse('禁止访问')           # 一旦有返回值,就会直接退出

    # 所有的请求走了,都会执行process_response
    def process_response(self, request, response):
        print('请求走了1')
        return response                            # 必须return response

    # 路由匹配成功,在视图函数执行之前执行process_view
    def process_view(self, request, callback, callback_args, callback_kwargs):
        # print(callback)
        # print(callback_args)
        # print(callback_kwargs)
        #
        # res=callback(request)                     # callback即为视图函数,可以主动调用
        #
        print("中间件1的process_view")
        # return res


class MyMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('请求来了2')
        # print(request.session)
        # return HttpResponse('dsb')

    def process_response(self, request, response):
        print('请求走了2')
        return response

    # 全局异常捕获,返回4开头的
    def process_exception(self, request, exception):
        print(exception)
        print('exception')
        return render(request, 'error.html')
# views.py
from django.shortcuts import render, HttpResponse, redirect


# Create your views here.


# def index(request):
#     print('我是视图函数')
#
#     return HttpResponse('ok')


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 hack(request):
    return render(request, 'hack.html')


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_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('登录成功')
// 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>

{#<form action="" method="post">#}
{#    {{ csrf_token }}#}
{#    {% csrf_token %}#}
{#    <p>用户名<input type="text" name="name"></p>#}
{#    <p>密码<input type="password" name="password"></p>#}
{#    <p><input type="submit" value="提交" id="submit"></p>#}
{#</form>#}


</body>


{# ajax方法 #}
{#方式一:放到data中#}
{#    'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]'),val(),#}
{#方式二:放到data中#}
{#    'csrfmiddlewaretoken':'{{ csrf_token }}'        (需要加引号,渲染成字符串)#}
{#方式三:放到头中#}
{#    headers:{'X-CSRFToken':'{{csrf_token}}'},#}

<script>
    /*
    $("#submit").click(function () {
        {#var sessionid=$.cookie('sessionid')#}
        $.ajax({
            url: '/csrf_test/',
            method: 'post',
            headers:{'X-CSRFToken':'{{csrf_token}}'},
            data: {
                'name': $('[name="name"]').val(),
                'password': $('[name="password"]').val(),

            },
            success: function (data) {
                console.log('成功了')
                console.log(data)

            },
            error: function (data) {
                console.log('xxxxx')
                console.log(data)

            }
        })

    })
    */


    $("#submit").click(function () {
        {#var sessionid=$.cookie('sessionid')#}
        $.ajax({
            url: '/csrf_test/',
            method: 'post',
            data: {
                'name': $('[name="name"]').val(),
                'password': $('[name="password"]').val(),

            },
            success: function (data) {
                console.log('成功了')
                console.log(data)

            },
            error: function (data) {
                console.log('xxxxx')
                console.log(data)

            }
        })

    })

</script>

</html>

 

posted @ 2020-10-25 20:02  板鸭没有腿  阅读(101)  评论(0)    收藏  举报