Fork me on GitHub

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 固定
posted @ 2019-11-13 14:30  是阿凯啊  阅读(122)  评论(0编辑  收藏  举报