zoukankan      html  css  js  c++  java
  • 59 Cookie 与 Session

    Cookie

    Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。

    客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。

    当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

    Cookie与HTTP头

    Cookie是通过HTTP请求和响应头在客户端和服务器端传递的: 

    • Cookie:请求头,客户端发送给服务器端; 
    • 格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;  Set-Cookie:响应头,服务器端发送给客户端; 
    • 一个Cookie对象一个Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C  

    Cookie的覆盖 

    如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。 

    django中的cookie语法

    1.cookie:
      1.每一个客户端浏览器针对每一个服务器维持信息的一个键值对结构
      2.信息保存在客户端
      3.每次发请求都会带着这个类似于字典的结构
      4.服务器可以读写cookie字典

    2.设置cookie

    响应对象:rep =HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect()
    响应对象.set_cookie("k1","v1",时间)

    rep.set_cookie(key,value,时间)

    rep.set_signed_cookie(key,value,salt='加密盐',...) 

    3.获取cookie

      request.COOKIES

      value = request.COOKIES.get(key)

     4.删除cookie

      response.delete_cookie("cookie_key",path="/",domain=name)

    '''
    class HttpResponseBase:
    
            def set_cookie(self, key,                 键
                         value='',            值
                         max_age=None,        超长时间 
                                  cookie需要延续的时间(以秒为单位)
                                  如果参数是 None`` ,这个cookie会延续到浏览器关闭为止。
    
                         expires=None,        超长时间
                                     expires默认None ,cookie失效的实际日期/时间。 
                                    
    
                         path='/',           Cookie生效的路径,
                                                     浏览器只会把cookie回传给带有该路径的页面,这样可以避免将
                                                     cookie传给站点中的其他的应用。
                                                     / 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
                         
                                 domain=None,         Cookie生效的域名
                                                    
                                                      你可用这个参数来构造一个跨站cookie。
                                                      如, domain=".example.com"
                                                      所构造的cookie对下面这些站点都是可读的:
                                                      www.example.com 、 www2.example.com 
                                     和an.other.sub.domain.example.com 。
                                                      如果该参数设置为 None ,cookie只能由设置它的站点读取。
    
                         secure=False,        如果设置为 True ,浏览器将通过HTTPS来回传cookie。
                         httponly=False       只能http协议传输,无法被JavaScript获取
                                                     (不是绝对,底层抓包可以获取到也可以被覆盖)
                      ): pass
    
    '''
    复制代码
    获取cookie:
    cookie源码

    5.登录时cookie的应用

    def login(request):
    
        if request.method=="GET":
            return render(request,"login.html")
        else:
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
    
            user_obj=UserInfo.objects.filter(name=user,pwd=pwd).first()
            if user_obj:
                # obj=HttpResponse("登录成功!")
                obj=redirect("/index/") #登录成功,重定向到index首页
                obj.set_cookie("is_login",True,20) #设置cookie
                obj.set_cookie("username",user) #设置cookie
            
                return obj
            return HttpResponse("Error!")
    
    def index(request):
    
        print("request.COOKIES",request.COOKIES)
        is_login=request.COOKIES.get("is_login")#获取cookie
        username=request.COOKIES.get("username") #获取cookie
    
        if not is_login: # 未登陆过
            return redirect("/login/")
    
        return render(request,"index.html",{"username":username})

     Session

    seesion为服务端技术,  服务器在运行时可以 为每一个用户的浏览器创建一个其独享的session对象,由于 session为用户浏览器独享,所以用户在访问服务器的web资源时 ,可以把各自的数据放在各自的session中,当用户再去访问该服务器中的其它web资源时,其它web资源再从用户各自的session中 取出数据为用户服务。

    1.Django中session语法

    1、设置Sessions值
              request.session['session_name'] ="admin"
    2、获取Sessions值
              session_name = request.session["session_name"]
    3、删除Sessions值
              del request.session["session_name"]
    4、flush()
         删除当前的会话数据并删除会话的Cookie。
         这用于确保前面的会话数据不可以再次被用户的浏览器访问
                
    5、get(key, default=None)
      
    fav_color = request.session.get('fav_color', 'red')
      
    6、pop(key)
      
    fav_color = request.session.pop('fav_color')
      
    7、keys()
      
    8、items()
      
    9、setdefault()
      
     
    10 用户session的随机字符串
            request.session.session_key
       
            # 将所有Session失效日期小于当前日期的数据删除
            request.session.clear_expired()
       
            # 检查 用户session的随机字符串 在数据库中是否
            request.session.exists("session_key")
       
            # 删除当前用户的所有Session数据
            request.session.delete("session_key")
       
            request.session.set_expiry(value)
                * 如果value是个整数,session会在些秒数后失效。
                * 如果value是个datatime或timedelta,session就会在这个时间后失效。
                * 如果value是0,用户关闭浏览器session就会失效。
                * 如果value是None,session会依赖全局session失效策略。
    View Code

    2.session 技术流程

    1.写session
      request.session["k"]=v
      过程:
        1.创建随机字符串

        2.在django-session表中创建记录
          session-key     session-data
          随机字符串       {“k":"v1"}

        3.响应对象.set_cookie("sessionid",随机字符串)

    2.读session
      request.session.get("k")
      过程:
        1.取钥匙 request.COOKIES.get('sessionid')
        2.在django-session表中查询记录:session-key=钥匙
        3.通过对象.k将值返回

    3.删session

      request.session.flush()
      过程:
        1.取钥匙 request.COOKIES.get("sessionid")
        2.在django-session表中查询记录:seesion-key=钥匙
        3.对象删除

    3.session 的应用 图片验证的生成

    用图片PIL 时,需要先安装  pillow 模块    ,  pip  install   pillow 

    过程简单分析:

      1.  客户访问login页面  login页面一加载, 遇到  <img src="/verify/" alt="" width="120px" height="40px">,向服务端发请求,到  "/verify/"路径

      2.后端 django  路由中,走path("verify/" , views.verify)

      3. 走 视图函数中:verify 函数,该函数通过一系列处理,得到一个验证码图片数据

    1.前端login页面:

    <body>
    {% csrf_token %}
    <div class="nav">图书管理系统</div>
    
    <div class="login">
            <div class="head"><h3>登录页面</h3></div>
            <div class="username">
    
                <label for="username">用户名:</label>
                <input type="text" class="user"  id="user" name="username" placeholder="请输入用户名">
            </div>
    
            <div class="pwd">
                <label for="password">&nbsp;&nbsp;&nbsp;:</label>
                <input type="text" class="" name="password" placeholder="请输入密码" id="password" >
            </div>
            <div class="verify">
                <label for="verify">验证码:</label>
                <input type="text" name="verify" id="verify"><img src="/verify/" alt="" width="120px" height="40px">
    
            </div>
            <div class="error"></div>
            <div class="btn" >
                登录
            </div>
    
    </div>
    
    
    <script>
        $(".btn").click(function () {
            username = $("#user").val();
            password = $("#password").val();
            verify = $("#verify").val();
            $.ajax({
                url:"/login/",
                data:{
                    username:username,
                    password:password,
                    verify:verify,
                    "csrfmiddlewaretoken":$('[name="csrfmiddlewaretoken"]').val()
                },
                type:"post",
                success:function (res) {
                    res = JSON.parse(res);
                    if (res["user"]){
                        //登录成功,跳转到books 页面
                        location.href="/books/";
    
                    }else {
                        //登录失败
                        $(".error").html(res["msg"]).css("color","red");
                        //1秒钟或提示语句消失,设置定时器
                        setTimeout(function () {
                            $(".error").html("");
                        },2000)
    
                    }
    
                }
    
            })
            }
        )
    </script>
    View Code

    2.后端路由

    urlpatterns = [
        path('admin/', admin.site.urls),
    
        path('books/', views.books),
        path('login/',views.login),
        path('verify/',views.verify),
        path('books/add/', views.add),
        re_path('books/del/(d+)/', views.delbook),
        re_path('books/edit/(d+)/', views.edit),
        re_path('del_a/', views.del_a),
    
    
    ]

    3.后端 视图

    def verify(request):
        #方式一
        import PIL
        from PIL import Image
        # img = Image.new("RGB",(120,40),get_random_color())
        # f = open("verify.png","wb")
        # img.save(f,"png")
        # with open("verify.png","rb") as f:
        #     data =f.read()
        # return HttpResponse(data)
    
        #方式二:
        # from io import BytesIO
        # img = Image.new("RGB",(120,40),get_random_color())
        # f = BytesIO()
        # img.save(f,"png")
        # data = f.getvalue()
        # return HttpResponse(data)
    
        # 方式3
        from io import BytesIO
        from PIL import ImageDraw,ImageFont
        img = Image.new("RGB",(120,40),get_random_color())
        draw = ImageDraw.Draw(img)
        font = ImageFont.truetype("static/font/kumo.ttf",28)
        keep_str=""
        for i in range(5):
            random_num =str(random.randint(0,9))#随机数字
            random_low_alpha =chr(random.randint(97,122)) #随机小写字母
            random_upper_alpha =chr(random.randint(65,90)) #随机大写字母
            random_char=random.choice([random_num,random_low_alpha,random_upper_alpha])#从列表中随机选一个
            #text((x轴坐标值,y轴坐标值),要写的内容,随机颜色,font=字体形式)
            draw.text((20+i*20,0),random_char,get_random_color(),font=font)
            #拼接随机字符串
            keep_str+=random_char
    
        print(keep_str)
        #set值session 值, key_str =为随机字符串,供用户登录输入验证码的值和这个随机字符串做比对验证
        request.session["keep_str"]=keep_str
        # 噪点噪线
        # width=250
        # height=40
        # for i in range(10):
        #     x1=random.randint(0,width)
        #     x2=random.randint(0,width)
        #     y1=random.randint(0,height)
        #     y2=random.randint(0,height)
        #     draw.line((x1,y1,x2,y2),fill=get_random_color())
        #
        # for i in range(100):
        #     draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
        #     x = random.randint(0, width)
        #     y = random.randint(0, height)
        #     draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
    
        f= BytesIO()
        img.save(f,"png")
    
        data =f.getvalue()
    
        #返回的数据直接在前端img    <img src="/视图函数/" alt="" width="120px" height="40px">
        # 返回的数据直接在前端img    <img src="/verify/" alt="" width="120px" height="40px">
        return HttpResponse(data)
    View Code

    6.session 的源码分析过程

    中间件
      
            解析session中间件:
                 class SessionMiddleware(MiddlewareMixin):
                        def __init__(self, get_response=None):
                            self.get_response = get_response
                            engine = import_module(settings.SESSION_ENGINE)
                            self.SessionStore = engine.SessionStore
    
                        def process_request(self, request):
                            session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
                            request.session = self.SessionStore(session_key)
    
                        def process_response(self, request, response):pass
                
                一旦请求发生:
                (1)  执行process_request:
                         确定这次是否有sessionid对应的cookie值,赋值给self._session_key 
                         request.session是SessionStore类的实例对象
                         
                (2)
                    def  视图函数:
                          request.session["k1"]="v1"
                          request.session["k2"]="v2"
                          
                    def 视图函数2:
                          request.session.get("k1")
                    
                    调用的request.session对象的setitem方法: 
                    
                    
                    class SessionBase():
                    
                        def __setitem__():
                            self._session[key] = value
                            self.modified = True
                        
                        _session = property(_get_session)                    
                        def _get_session(self, no_load=False):
         
                            self.accessed = True
                            try:
                                return self._session_cache
                            except AttributeError:
                                if self.session_key is None or no_load:
                                    self._session_cache = {}
                                else:
                                    self._session_cache = self.load()
                            return self._session_cache
                            
                            
                (3) 执行 process_response:
                            request.session.save()
                            
                            def save():
                            
                                # 创建随机字符串:
                                self._session_key = self._get_new_session_key()
                                # 创建对讲或者更新对象
                                self.model(
                                            session_key=self._get_or_create_session_key(),
                                            session_data=self.encode(data),
                                            expire_date=self.get_expiry_date(),
                                            )
                                                            
                            # 设置cookie
                            response.set_cookie(
                                settings.SESSION_COOKIE_NAME,
                                request.session.session_key, max_age=max_age,
                                expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
                                path=settings.SESSION_COOKIE_PATH,
                                secure=settings.SESSION_COOKIE_SECURE or None,
                                httponly=settings.SESSION_COOKIE_HTTPONLY or None,
                                samesite=settings.SESSION_COOKIE_SAMESITE,
                            )
    session源码解析过程
  • 相关阅读:
    深度学习代码注解(一)—— mnistdeepauto
    只属于你我的共同记忆
    只属于你我的共同记忆
    道教的认识
    道教的认识
    作家、文学大家、大师的艺术风格
    作家、文学大家、大师的艺术风格
    视频、画面、语言、文字与脑海、心灵
    视频、画面、语言、文字与脑海、心灵
    URAL 1963 Kite 四边形求对称轴数
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10249729.html
Copyright © 2011-2022 走看看