美文网首页
cookie和Session

cookie和Session

作者: Camilia_yang | 来源:发表于2019-08-19 12:07 被阅读0次

    cookie篇

    背景(可略过直接看:cookie简介)

    在开始介绍cookie之前,我们先思考一个问题:我们通常说的web应用程序的无状态性的含义是什么?
    直观的说,“每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况”
    要明白,这句话的含义是指在说明,http协议作为技术背景的web应用程序请求——应答模式是无状态的,这个事实基本不会发生改变,也不会因为加入cookies、session机制而变成有状态的。要明白,这种前后因果关系:“我们要实现的是一种web应用,实现这种应用的协议我们选择了http这种本质上是无状态的通信协议。但是事实上,我们需要我们的web应用是有状态的。所以我们加入了cookies、session等机制去实现由状态的web应用”。所以我们可以这么理解:

    Web应用=http协议+session、cookies等状态机制+其他辅助的机制。

    其实,应用程序(软件通信)的状态与否是一个非常通用的概念。我们可知,在网络协议中,我们称TCP为一个有状态的传输层通信协议,而UDP则不是;IP是无状态的。要明白这种状态与否的判定,是面向你这一层次所指实现的功能——是否由上下文决定——来判定的(是否受之前的通信过程直接影响、是否直接影响之后的通信过程).
    下面这副图中,是关于网络应用层次中的各层次的有无状态情况

    image.png
    支持协议(下层)的有无状态,消费协议(上层)的有无状态,没有直接的关系。还是那句话,每层协议的有无状态关系到它的本身功能执行的时候的有无状态地特点。
    (1)IP是无状态的,它只负责将一个IP包发送到指定的IP地址上去。它不会考虑这个包与前面已经发送的包和后面的包的联系。(可能是重发包、可能是不连续包,它不管)。

    (2)TCP是有状态的,它通过包头中的一些控制字段(序列编码等)来表明各个包之间的关系(前后关系,重包与否等等)。所以,通过这个协议你可以做到一个可靠的传输。那么TCP是面向连接的协议是什么意思呢?其实这里的面向连接其实就是“三次握手”。三次握手,首先可以保证对方的存在,其次握手的所交换的内容是为将来进行有状态的传输做准备。

    (3) UDP是无状态的,它仅仅是在IP上加了Port,其他的事情什么也不干。这样它不可能做到可靠的传输,同样也不需要连接。

    (4) HTTP是无状态的,它的底层协议是由状态的TCP,但是HTTP的一次完整协议动作,里面是使用有状态的TCP协议来完成的。而每次协议动作之间没有任何关系。例如:第7次请求HTTP协议包,并不知道,这个包是为了什么?它或许是因为上次没有请求成功而重传,或许是上次的后续请求,或许是其他的,这些HTTP自身都不知道。

    (5) www应用,但是很多时候,www应用是需要HTTP动作之间是有关联的,那就是使应用有状态。这样才能提供给用户最好的用户体验。

    HTTP会设计成无状态是有历史原因的,在www应用还很简单的时候,这个应用只是被用来浏览内容。无状态的协议已经够了,这样实现可以减轻实现的负担,因为有状态的协议实现起来代价相对来说是很高的。

    因为我们都是使用无状态的HTTP协议传输出数据,这意味着客户端与服务端在数据传送完成后就会中断连接。这时我们就需要一个一直保持会话连接的机制。在session出现前,cookie就完全充当了这种角色。也就是,cookie的小量信息能帮助我们跟踪会话。一般该信息记录用户身份。
    好了,下面正式介绍cookie

    cookie简介

    Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息。
    例如,如果在用户请求站点中的页面时应用程序发送给该用户的不仅仅是一个页面,还有一个包含日期和时间的 Cookie,用户的浏览器在获得页面的同时还获得了该 Cookie,并将它存储在用户硬盘上的某个文件夹中。(一般是C盘)
    以后,如果该用户再次请求您站点中的页面,当该用户输入 URL 时,浏览器便会在本地硬盘上查找与该 URL 关联的 Cookie。如果该 Cookie 存在,浏览器便将该 Cookie 与页请求一起发送到您的站点。然后,应用程序便可以确定该用户上次访问站点的日期和时间。您可以使用这些信息向用户显示一条消息,也可以检查到期日期。
    Cookie 与网站关联,而不是与特定的页面关联。因此,无论用户请求站点中的哪一个页面,浏览器和服务器都将交换 Cookie 信息。用户访问不同站点时,各个站点都可能会向用户的浏览器发送一个 Cookie;浏览器会分别存储所有 Cookie。
    Cookie 帮助网站存储有关访问者的信息。一般来说,Cookie 是一种保持 Web 应用程序连续性(即执行状态管理)的方法。除短暂的实际交换信息的时间外,浏览器和 Web 服务器间都是断开连接的。对于用户向 Web 服务器发出的每个请求,Web 服务器都会单独处理。但是在很多情况下,Web 服务器在用户请求页时识别出用户会十分有用。例如,购物站点上的 Web 服务器跟踪每位购物者,这样站点就可以管理购物车和其他的用户特定信息。因此,Cookie 可以作为一种名片,提供相关的标识信息帮助应用程序确定如何继续执行。

    cookie的存储

    Cookies保存在用户的本地机器上,不同的浏览器存储在不同的文件夹中,并且按照域名分别保存。即网站之间的Cookies不会彼此覆盖。
    IE浏览器的用户可以通过在本地的文档中找到Cookies的txt文件, 不同操作系统的位置不同,windows server 2003/xp都保存在:
    C:\Documents and Settings\Administrator\Cookies 文件夹下。

    cookie如何传递

    cookie的信息是在Web服务器和浏览器之间传递的。保存在Http请求中。
    (1)请求页面
    在请求一个页面的Http头中,会将属于此页面的本地Cookies信息加在Http头中:

    GET /Cookies/Test.aspx HTTP/1.1 
    Host: localhost:1335 
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 3.5.30729) 
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8 
    Accept-Language: zh-cn,zh;q=0.5 
    Accept-Encoding: gzip,deflate 
    Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 
    Keep-Alive: 300 
    Connection: keep-alive 
    Cookie: My.Common.TestCookieInfo=Pkid=999&TestValue=aaabbbcccdddeee 
    

    (2)响应页面
    如果页面要求写入Cookies信息,则返回的Http如下:

    HTTP/1.x 200 OK 
    Server: ASP.NET Development Server/9.0.0.0 
    Date: Thu, 06 Aug 2009 03:40:59 GMT 
    X-AspNet-Version: 2.0.50727 
    Set-Cookie: My.Common.TestCookieInfo=Pkid=999&TestValue=aaabbbcccdddeee; expires=Fri, 07-Aug-2009 03:40:59 GMT; path=/ 
    Cache-Control: <span class="kwrd">private</span> 
    Content-Type: text/html; charset=utf-8 
    Content-Length: 558 
    Connection: Close 
    

    cookie的生效时间及其他几个重要特性:
    expires/Max-Age字段:为cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。默认是在页面关闭后(会话关闭)失效,即浏览器关闭(不是浏览器标签页,而是整个浏览器) 后失效。但后台可以任意通过该字段设置过期时间。
    Size字段:此cookie大小。
    domain字段:为可以访问此cookie的域名。
    http字段 :cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。

    试着总结一下cookie:
    1、服务器通过Set-cookie头给客户端一串字符串
    2、客户端每次访问相同域名(同源)的网页时,必须带上这段字符串。
    3、客户端要在一段时间内保存这个Cookie

    Cookie的缺陷:

    ①Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
    ②由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题。(除非用HTTPS)
    ③Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的。
    建议:前端最好不要去写cookie,cookie能小则小,因为会拖慢页面的请求。一般情况都是只存sessionId(或其他id)

    Session篇

    Session存储在服务器端,Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。

    Session的意义何在?

    Session存在的意义是为了提高安全性,它将关键数据存在服务器端。
    客户端只保存sessionId到cookie中,而不会保存Session,Session销毁只能通过invalidate或超时,关掉浏览器并不会关闭Session。与cookie不同,cookie则是将数据存在客户端的浏览器中。
    因为cookie是较为危险的,若客户端遭遇黑客攻击,信息容易被窃取,数据也可能被篡改,而运用Session可以有效避免这种情况的发生。

    Session什么时候失效?

    1. 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为30分钟。
    2. 调用Session的invalidate方法。

    Session对浏览器的要求:

    虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
    该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

    注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择"在新窗口中打开"时,子窗口便可以访问父窗口的Session。

    如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写

    URL地址重写

    URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户sessionId信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id(服务器通过query.sessionId拿到URL中的sessionId)。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String url)实现URL地址重写,该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。

    注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。

    image.png
    image.png
    简单来说,Session就是服务器内存中储存用户隐私信息的对象(哈希表),服务器和浏览器交流数据的过程是这样的:
    1.服务器通过cookie给客户端一个sessionId,
    2.每次客户端访问服务器的时候,服务器读取SessionID
    3.服务器有一块内存(对象)保存了所有Session
    4.通过SessionID我们可以得到对应用户的隐私信息,如id,email
    sessionId是一个随机生成的,没有规律的随机数,所以别人是猜不到你的sessionId是多少的。所以被篡改,也没有关系。如果用户不(shou)小(jian)心将sessionId删掉,那就只能重新登录。

    那么如果通过暴力穷举才猜测随机数有没有可能呢?
    比方,我们的sessionId是通过下面这行代码生成的:

    sessionId=Math.random()*100000
    

    那么,sessionId就是一个16位数,每一位有10种可能(0-9),就有10^16 种可能,已经很大了;如果加上字母,每一位就有36种可能(0-9,a-z),就有36^16 种可能。假设发一次请求耗时1s,一天84600s,发36^16 个请求可能要发到一千年以后了,所以....基本不可能啦,随机数万岁!

    参考:

    https://www.cnblogs.com/zhangziqiu/archive/2009/08/06/cookies-javascript-aspnet.html
    https://blog.csdn.net/qq_29132907/article/details/80390792
    https://www.cnblogs.com/shizhijie/p/8422662.html

    相关文章

      网友评论

          本文标题:cookie和Session

          本文链接:https://www.haomeiwen.com/subject/ponjsctx.html