• cookie与session,还有中间件


    cookie与session,还有中间件

    一、cookie与session

    ​ HTTP协议是无状态的,如果需要保存数据,也就是“保持状态”,就需要用到cookie。

    ​ Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。

    ​ cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,服务器能通过Cookie的内容来判断用户身份。

    obj = HttpRespones()
    # 设置cookie
    obj.set_cookie(key, value,...)
    # 获取
    request.CKKOIES.get()
    # 删除
    obj.delete_cookie()
    # 设置标签
    obj.set_signed_cookie(key, value, salt='加盐', max_age=None,...)
    # 其他属性:dafault 默认值  expires 超过时间 domain 生效域名  path 路径
    

    ​ 登录校验(cookie):

    from django.shortcuts import render,HttpResponse,redirect
    
    def login(request):
        if request.mothed == 'POST':
            username = request.POST.get('username')
            pwd = request.POST.get('pwd')
            if username == 'lalala' and pwd == '123':
                old_path = request.GET.get('next')
                if old_path:
                    # 保存用户一登陆状态
                    obj = redirect(old_path)
                else:
                    obj = redirect('/home/')
                obj.set_cookie('name', 'lalala') #让浏览器记录一个键值对
                return obj
        return render(request, 'login.html')
    

    1.2 session

    ​ cookie一定程度上解决了保持状态的需求,但是由于其容量小(4096字节),而且保存在本地客户端,致使存在安全隐患。session保存在服务端,而且容量大,可以解决cookie安全性低的问题。

    ​ 每个客户端的cookie被分配了唯一的id,服务端通过id识别用户身份,并将登录信息保存在session或者与已保存在session中的信息配对对比,完成身份存储和校验。

    # 设置session
    request.session['key'] = value  # 此时进产生一个缓存
    '''
                1.django内部自动生成了随机的字符串
                2.在django_session表中存入数据
                    session_key          session_data         date
                    随机字符串1              数据1              ...
                    随机字符串2              数据2              ...
                    随机字符串3              数据3              ...
                3.将产生的随机字符串发送给浏览器 让浏览器保存到cookie中
                    sessionid:随机字符串
    
    '''
    # 获取session
    request.session.get('key')
    '''
    		1.浏览器发送cookie到django后端之后 django会自动获取到cookie值
             2.拿着随机字符串去django_session表中比对 是否有对应的数据
             3.如果比对上了 就讲随机字符串所对应的数据 取出赋值给request.session
             4.如果对不上 那么request.session就是个空
             注意:django session表是针对浏览器的,不同的浏览器来 才会有不同的记录
    '''
    # 删除session
    request.session.delete()  # 只删除服务端的session
    request.session.flush()   #浏览器和服务端的都删除
    # 设置超时
    request.session.set_expiry(value)
    '''
    		value: 数字       --->数值秒后失效
    			   0         --->关闭浏览器后失效
        		   不写       --->依赖全局session失效
            	   时间格式    --->时间后失效
    		django session默认的过期时间是14天
    '''
    # 检查key是否存在
    request.session.exists('session_key')
    # 删除所有失效日期小与当前日期的session
    request.session.clear_expired 
    

    ​ 登录校验(session):

    from functools impory wraps
    
    def check_login(func):
        @wraps(func)
        def inner(request, *args, **wkargs):
            next_url = request.get_full_path()
            if request.session.get('user'):
                return func(request, *args, **kwargs)
            else:
                return redirect('/login/?next={}'.format(next_url))
            return inner
       
    def login(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            
            if user == 'lalala' and pwd == '123':
                # 设置session
                request.session['user'] = user
                # 获取到跳转到登录页面之前的url
                next_url = request.GET.get('next')
                if next_url:
                    return redirect(next_url)
                else:
                    return redirect('/index/')
        return render(request,'login.html')
    
    @check_login
    def logout(request):
        request.session.delete()
        return redirect('/login/')
    
    @check_login
    def index(request):
        current_user = request.session.get('user',None)
        return render(request,'index.html',{'user':current_user})
       
    

    二、中间件

    ​ 中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

    img

    ​ django中间件共有七层,每层功能各不一样,暴露给程序员五个可以自定义的方法(五个方法都是在特定的条件下自动触发的)。

    # 1.新建一个任意名的py文件,写任意名的类,固定继承:
    from django.utils.deprecation import MiddlewareMixin
    class M(MiddlewareMixin):
        ...
        
    # 2.在配置文件中注册中间件配置,手写路径
    

    ​ 五种自定义方法:

    # 1.process_request:优先于视图函数进行执行,如有多个中间件时,灰暗这MIDDLEWARE中注册顺序,从上向下依次执行。不同的中间件之间传递的request是同一个对象
    
    # 2.process_response:落后于视图函数进行执行,按照倒叙的顺序进行。
    
    # 3.process_view:路由匹配成功之后执行视图函数之前触发
    
    # 4.process_exception:当视图函数出现异常(bug)的时候自动触发
    # 5.process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发
    

    三、跨站请求伪造

    ​ 跨站请求伪造(Cross-site request forgery),也被称为 one-click attack 或session riding,通常缩写为 CSRF*或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

    ​ 例如银行汇款,填写的form表单中,用户名密码都是真实提交给银行后台的,但是收款人的账户虽然填写的是被转账对象的,但是实际填写的是一个没有name属性的input框,实际转账的用户是提前写好的隐藏的带有name和value的input框。

    ​ 解决方法:用户进入提交post请求的页面就返回一个随机的字符串,当用户提交请求时,会先自动校验这个字符串,正确就可以正常提交,匹配不正确就报403。

    ​ form表单:

    <body>
        <h1>真正的网站</h1>
        <form action="" method="post">
            { % csrf_token % }   # 加这条代码就可以
            <p>username:<input type="text" name="username"></p>
        	<p>target_user:<input type="text" name="target_user"></p>
        	<p>money:<input type="text" name="money"></p>
        	<input type="submit">
        </form>
    </body>
    

    ​ ajax:

    <body>
        { % csrf_token % }
        <script>
            %('#b1').click(function()){
            	$.ajax({
                	url:"",
                    type:"post",
                	data:{'username':'lalala'},
                	success:function(data){
                        alter(data)
                    }
                 })
         	}
        </script>
    </body>
    # 方法一:data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
    
    # 方法二:data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
    

    ​ 方法一与方法二都是通过{% csrf_token %}获取到随机字符串,再利用标签查找。

    ​ 方法三,导入一个相应功能的js文件。

    四、CBV视图中使用装饰器

    ​ 1.csrf_exempt:

        from django.views.decorators.csrf import csrf_exempt, csrf_protect
        from django.utils.decorators import method_decorator
            # 第一种
        # @method_decorator(csrf_exempt,name='dispatch')
        class MyCsrf(View):
            # 第二种
            @method_decorator(csrf_exempt)
            def dispatch(self, request, *args, **kwargs):
                return super().dispatch(request,*args,**kwargs)
            def get(self,request):
                return HttpResponse('hahaha')
    

    ​ 除了csrf_exempt之外 所有的其他装饰器 在CBV上面都有三种方式:

    @method_decorator(csrf_protect,name='post')
        class MyCsrf(View):
            @method_decorator(csrf_protect)
            def dispatch(self, request, *args, **kwargs):
                return super().dispatch(request,*args,**kwargs)
            def get(self,request):
                return HttpResponse('hahaha')
    
            @method_decorator(csrf_protect)
            def post(self,request):
                return HttpResponse('post')
    
  • 相关阅读:
    IE表单拦截器
    使用网站作为WCF服务宿主的几种做法
    Javascript执行效率小结
    Ajax无刷新技术实现省市县三级联动下拉菜单Asp.Net
    序列化DataContractSerializer
    变化多端的列表
    腾讯微信
    Mac OS 和 iOS 操作系统架构
    程序员远离你的细节思维
    ObjectiveC概述
  • 原文地址:https://www.cnblogs.com/tangceng/p/11768053.html
Copyright © 2020-2023  润新知