• Django:Cookie和session


    2.1Cookie

    Cookie的由来

    • HTTP协议是无状态的
    • 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
    • 状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。

    什么是Cookie

    • Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
    • cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。

    查看Cookie

    • 使用Chrome浏览器,打开开发者攻击查看

    应用:

    • 登录
    • 保存浏览习惯
    • 简单的投票

    Django中操作Cookie

    • 设置/获取Cookie

      #第一种方法普通获取/设置:
      #set_cookie         设置
      class Login(View):
          def get(self,request):
              pass
          def post(slef.request):
              #获取重定向对象
      		ret = redirect(url)
               ret.set_cookie("login","1")#设置cookie为{"login":"1"}
               ...
                
      #request.COOKIES.get(键)       获取
      def login_required(func):#login_required函数是装饰器函数
          def inner(request,*args,**kwargs):
              login = request.COOKIES.get("login")
              print(login)
              url = request.path_info
              if login != "1":
                  return redirect("/login/?return_url={}".format(url))
              ret = func(request,*args,**kwargs)
              return ret
          return inner
      
      @login_required
      def foo(request):...
      
      #第二种方法加密获取:
      #设置
      rep.set_signed_cookie(key,value,salt='加密盐',...)
      参数:
      	key  键
          value  值
          max_age = None 超时时间
          expires = None 超时时间(IE浏览器使用)
          path = "/"   Cookie生效的路径
          domain = None   Cookie生效的域名
          secure = False   HTTPS传输
          httponly = False  只能http协议传输,无法被JavaScript获取(但不是绝对,底层抓包可以获取到也可以被覆盖)
      
      #获取
      request.get_signed_cookie('key', default="", salt='', max_age=None)
      参数:
      	key    键
          value  值
          max_age   后台控制过期时间
      
      
      ret.set_signed_cookie("login", "1", salt="yan")
              login = request.get_signed_cookie("login",salt="yan",default="")
      
      
      • 注意:当设置时候,不能有default="",当获取时候,应有default="",否则会报错

    当set_signed_cookie 设置max_age=21秒,表示21秒后Cookie就失效

    • 通过set_signed_cookie设置,get_signed_cookie获取 对比 set_cookie设置 ,request.COOKIES.get(键) 获取

      两者都是成对出现,缺一都不能使用

      set_signed_cookie设置会对cookies加密,但还是在Response Cookies显示出来,比如设置的1,在红色框内:

    • 当设置secure = True,可以看到Response Cookies 中loginSecure中打✔,只有HTTPS才能继续登录。

    • httponly = True 只能HTTP协议登录

    • 删除

      • 用途:删除用户浏览器上之前设置的user的cookie值
      ret = redirect("/login/")
      ret.delete_cookie("login")
      
      • 示例:用户退出

        def logout(request):
            ret= redirect("/login/")#退出回到登录页面
            ret.delete_cookie("login")#清除Cookie
            return ret
        

    2.2Session

    session由来

    • 需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。

      • 是由于Cookie本身最大支持4096字节。
      • Cookie本身保存在客户端,可能被拦截或窃取。
    • Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;但是Cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。

    • session保存在服务器上一组组键值对(必须依赖cookie),不需要进行传输

    • session存的数据放在关联数据库的django-session表中

    Session中方法

    • 设置session

      request.session[key] = values
      request.session.setdefault('k1',123)
      
    • 获取session

      request.session.get(key,None)
      
    • 删除session

      del request.session[key]
      
    • 用session实现登录验证

      class Login(View):
          def get(self,request):
              return render(request,"login.html")
          def post(self,request):
              username = request.POST.get("username")
              pwd = request.POST.get("pwd")
              obj = models.User.objects.filter(username=username,pwd=pwd)
              if obj:
                  url = request.GET.get("return_url")
                  if url:
                      ret = redirect(url)
                  else:
                      ret = redirect("/home/")
                  #设置session login
                  request.session['login'] = 1
      
      
                  return ret
      
              return render(request,"login.html",{"error":"用户名密码不正确"})
      
      def login_required(func):#装饰器,判断当前访问状态
          def inner(request,*args,**kwargs):
              #获取session 
              login = request.session.get("login")
              print(login)
              url = request.path_info
              if login != 1:
                  return redirect("/login/?return_url={}".format(url))
              ret = func(request,*args,**kwargs)
              return ret
          return inner
      
      
      @login_required
      def home(request):
          return render(request,"home.html")
      
      
      @login_required
      def index(request):
          return render(request,"index.html")
      
      
      • 由图可以看出sessionid = 数据库存储的session_key

    session流程分析:

    • 流程图

    • session表

    • 浏览器

    浏览器访问服务器,服务器会自动生成一个随机字符串,设置的值放置在一个字典当中,随机生成的字符串放在Django-session表中session-key字段,数据放在session-data中(加密后),expire_date是超时时间。并保存
    
    把数据库session-key随机字符串放在cookie里返回给浏览器,也就是sessionid。可以理解为sessionid为cookie ,value为返回随机字符串
    
    待到下次访问时会携带cookie(也就是sessionid),服务器会根据cookie从数据库中找到相应数据,再解密返回给浏览器。
    
    由此可知session不能独立使用,必须依赖于cookie使用
    

    session中其他方法

    • 获取所有,键、值、键值对

      request.session.keys()
      request.session.values()
      request.session.items()
      
    • 获取session_key

      request.session.session_key
      
    • 失效日期数据删除

      request.session.clear_expired()
      
      • 示例:删除失效数据

    • 检查会话session的key是否在数据库存在

      request.session.exists("session_key")
      
      • request.session.exists("session_key")

        def index(request):
            ret = request.session.session_key
            result= request.session.exists(ret)
            print(result)#True
            return render(request,"index.html")
        
    • 删除当前会话所有session数据,不删除cookie

      request.session.delete()
      
      • 退出,并在库中信息删除

        def logout(request):
            ret= redirect("/login/")
            request.session.delete()
            return ret
        
    • 删除当前会话session数据并删除会话cookie

      request.session.flush()
      
      • 当执行此语句

    • 设置会话session和Cookie的超时时间(超时后,cookie删除,但是数据库还有session)

      request.session.set_expiry(value)
      	如果value是整整数,session会在相应秒数后失效
      	如果value是个datatime获取timedelta,session就会在这个时间后失效
      	如果value是0,用户关闭浏览器session就会失效
      	如果value是None,session会依赖全局session失效策略
      
      • 示例:request.session.set_expiry(10)

    Django中的Session配置

    1. 数据库Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
    
    2. 缓存Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    
    3. 文件Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
    
    4. 缓存+数据库
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
    
    5. 加密Cookie Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
    
    其他公用设置项:
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    

    小技巧

    • 如何看session配置

      from django.conf import global_settings
      #ctrl + 鼠标左键点击global_settings进入文件global_settings.py然后搜索session,可以看到配置
      
    • 缓存配置

      from django.contrib.sessions.backends import db
      #ctrl + 鼠标左键点击db进入文件,通过以下操作可以看到session存在位置
      

    3.JQuery的cookie操作

    • 首先需要下载Jquery.cookie.js和jquery文件,jquery.cookie.js下载地址

      http://plugins.jquery.com/cookie/

      //连接jquery
      <script type="text/javascript" src="js/jquery.min.js"></script>
      <script type="text/javascript" src="js/jquery.cookie.js"></script>
      
    • 添加一个cookie

          <script>
              var res = $.cookie("the_cookie","the_value");
              console.log(res);
          </script>
      

    • 创建一个cookie并设置有效时间为7天

      $.cookie('the_cookie', 'the_value', { expires: 7, path: '/' });
      
    • 读取cookie

      $.cookie('the_cookie');
      
    • 删除cookie

      $.cookie('the_cookie', null);   //通过传递null作为cookie的值即可
      
    • 可选参数

      $.cookie('the_cookie','the_value',{
          expires:7, 
          path:'/',
          domain:'jquery.com',
          secure:true
      }) 
      
    • 参数

      expires:(Number|Date)有效期;设置一个整数时,单位是天;也可以设置一个日期对象作为Cookie的过期日期;
      path:(String)创建该Cookie的页面路径;
      domain:(String)创建该Cookie的页面域名;
      secure:(Booblean)如果设为true,那么此Cookie的传输会要求一个安全协议,例如:HTTPS;
      

    4.常用HTTP请求头

    协议头 说明 示例 状态
    Accept 可接受的相应内容类型(Content-Types Accept: text/plain 固定
    Accept-Charset 可接受的字符集 Accept-Charset: utf-8 固定
    Accept-Encoding 可接受的响应内容的编码方式。 Accept-Encoding: gzip, deflate 固定
    Cache-Control 用来指定当前的请求/回复中的,是否使用缓存机制。 Cache-Control: no-cache 固定
    Cookie 由之前服务器通过Set-Cookie(见下文)设置的一个HTTP协议Cookie Cookie: $Version=1; Skin=new; 固定:标准
    Host 表示服务器的域名以及服务器所监听的端口号。如果所请求的端口是对应的服务的标准端口(80),则端口号可以省略。 Host: www.itbilu.com:80``Host: www.itbilu.com 固定
    Referer 表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面。Referer其实是Referrer这个单词,但RFC制作标准时给拼错了,后来也就将错就错使用Referer了。 Referer: http://itbilu.com/nodejs 固定
    User-Agent 浏览器的身份标识字符串 User-Agent: Mozilla/…… 固定
    Content-Type 请求体的MIME类型 (用于POST和PUT请求中) Content-Type: application/x-www-form-urlencoded 固定

    5.常见HTTP响应头

    响应头 说明 示例 状态
    Cache-Control 通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒 Cache-Control: max-age=3600 固定
    Status 通用网关接口的响应头字段,用来说明当前HTTP连接的响应状态。 Status: 200 OK
    Location 用于在进行重定向,或在创建了某个新资源时使用。 Location: http://www.itbilu.com/nodejs
    Server 服务器的名称 Server: nginx/1.6.3 固定
    Date 此条消息被发送时的日期和时间(以RFC 7231中定义的"HTTP日期"格式来表示) Date: Tue, 15 Nov 1994 08:12:31 GMT 固定
    Connection 客户端(浏览器)想要优先使用的连接类型 Connection: keep-alive``Connection: Upgrade 固定
    Content-Length 以8进制表示的请求体的长度 Content-Length: 348 固定
  • 相关阅读:
    try catch finally中return的执行顺序
    多线程和同步
    orecle常用函数
    java如何调用接口 2
    orecle 函数
    ==和equals在比较字符串时候的区别
    orecle触发器
    java实现同步的方法
    java如何调用接口
    SMM+maven下的log4j配置打印sql
  • 原文地址:https://www.cnblogs.com/xujunkai/p/11848043.html
Copyright © 2020-2023  润新知