django16

昨日回顾

# 如果在浏览器上没有登陆,购买东西是能加入购物车,如果换了另一个浏览器,购物车就没有记录了,因为没有登录,所以存在了本地的浏览器的cookie中,登录后存在了服务端的数据库中
1 django中cookie的使用
	-增 obj.set_cookie(key,value,max_age)
    -删 obj.delete_cookie(key)   # 或者将cookie的value设置为空
    -查 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原理流程

image-20201023154624063

2 自定义中间件

1 # 自定义步骤:原来的相同中间件要注释
	-写一个类,一般写在app新py文件中继承MiddlewareMixin,导入from django.utils.deprecation import MiddlewareMixin
    -里面写方法process_request(所有的请求来了,一定会触发它的执行,request就是当次请求的request对象)
    -在setting中配置(注意,放在前和放在后是有区别的)
    	MIDDLEWARE = [
            ...
    		'app01.mymiddle.MyMiddleware1',
            ...
		]
# 如果将自己写的类放在配置文件的最前面,而类中只写了process_request,那么不会经过中间件django.contrib.sessions.middleware.SessionMiddleware,因此在自己写的类中request.session中取不到

3process_request,process_response,process_view,process_exception

1 process_request(request对象)  # 如果返回了,必须返回HttpResponse的对象,那么将相当于走process_request直接返回了,请求都没走到后面,如果没写,会继续走后面其他process_request。
2 process_response(request对象,response对象)  # 所有的请求走了都会执行它,必须返回一个response ,否则在出了django框架之后,就没有任何返回东西
3 多个中间件,执行顺序是什么?
	-请求来的时候从上往下执行:先执行每一个的process_request
    -请求走的时候,从下往上执行:在执行每一个的process_response
# 前提是process_response的时候必须返回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)  # 此就是视图函数,可以在这个之前或者之后写代码,就跟装饰器的作用一样,一般不这样用
            return res
7 process_exception 视图函数出错,会执行它(全局异常捕获)(记录日志,哪个ip地址,访问哪个路径,出的错)
    # 全局异常捕获,返回4开头的
    def process_exception(self, request, exception):
        print(exception)
        return render(request,'error.html')

image-20201023170151704

4 CSRF_TOKEN跨站请求伪造

1 跨站请求伪造
3 django解决了csrf攻击,中间件:django.middleware.csrf.CsrfViewMiddleware,该中间件只处理了post请求,在访问的时候,默认会在返回的页面中放入隐藏的随机字符串(js是无法操作另一个网页的)
4 后期中间件不能注释,每次发送post请求,都需要携带csrf_token随机字符串
	# -form表单提交 
    	-在form表单中 {% csrf_token%}   如果是{{ csrf_token }}就是一个变量
  # 每次请求都会在context(渲染模板用的)里面放一个csrf_token,然后会在模板中写入返回,以后每次请求来的时候,根据request中的key,取出对应的字符串,校验是不是本服务端签发的。
    # -ajax提交(如何携带)
    方式一:放到data中
     $.ajax({
            url: '/csrf_test/',
            method: 'post',
            data: {'name': $('[name="name"]').val(),  # 通过类,标签,或者属性取,此处是根据属性取
                'password': $('[name="password"]').val(),    'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()    #此处的key的值必须是csrfmiddlewaretoken,此时取得值是直接从前端取出的
            },
            success: function (data) {
                console.log('成功了')
                console.log(data)
            },
            error: function (data) {
                console.log('xxxxx')
                console.log(data)
            }
        })
        方式二:放到data中
        'csrfmiddlewaretoken':'{{ csrf_token }}'  # 注意'{{ csrf_token }}'此处一定要加''表示是字符串,此时取出的值是在后端渲染模板完成的值
        方式三:从cookie中取出(此处取出的值和其他的值不一样)是放到请求头中,那么模板页面中就不需要写{% csrf_token%}
         $.ajax({
            url: '/csrf_test/',
            method: 'post',
        	headers:{'X-CSRFToken':'{{csrf_token}}'},
             })
        
 # jquery.cookie.js   从请求头中取出cookie携带的csrf的随机字符串
	-在浏览器中对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)) #将视图函数当作参数传递给装饰器函数

image-20201023172124256

原文地址:https://www.cnblogs.com/feiguoguobokeyuan/p/13971308.html