我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第15篇文章,点击查看活动详情
在Cookie章节中,我们提到酒店A与公司协商达成的订餐协议并不具有关联性,即每一份 订餐协议的数据都是独立的,前后不具有关联性,是无状态的。为了解决这个问题满足酒店A能 识别订餐用户的需求,酒店A给每个公司发了具有唯一ID的通行证。在第二次订餐时,公司提 交订餐通行证,酒店A就能直接识别该公司的订餐信息了。这个通行证就相当于一个身份认证, 它将不同阶段的数据传输用指定的方式进行关联,合理解决了订餐协议的无状态性。在公司这边 的通行证就是技术中的Cookie。所有针对个人的订餐信息均由公司自己保存。那么问题来了,如 果公司丢失了通行证怎么办?酒店A难道就不保留公司信息吗?酒店A会创建公司的“订餐明细 表”用于保存及确认公司的身份。如果说Cookie 机制是通过检查公司身上的“通行证”来确定公 司身份的话,那么 Session 机制就是通过检查酒店A的“公司订餐明细表”来确认公司身份,当 公司需要订餐时只需要查询订餐明细表就可以为相应的公司提供配菜服务了。
同样为解决订餐协议的无状态性,Session 是另一种记录用户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而Session 保存在服务器上。它是服务器端对于无状态协议的一种解决方案。客户端访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是Session。客户端再次访问时只需要从该Session 中查找该用户的状态即可,如图所示。
Session的传输步骤如下。
(1)服务器端程序运行的过程中创建Session,并且为该Session生成唯一的 Session ID。
这个Session ID在随后的请求中会被用来重新获得已经创建的Session。在Session 被创建之后,就可以调用Session相关的方法向Session中增加内容,这些内容只会保存在服务器中。
(2)服务器将Session ID发到客户端。
(3)当客户端再次发送请求的时候,会将这个Session ID带上。
(4)服务器接收到请求之后就会依据 Session ID找到相应的Session,完成请求响应。Session的传输媒介
1.通过Cookie 传输
Session的信息是保存在服务器端的。测试人员只需要运用抓包工具从Cookie中获取 SessionID的值用于模拟用户请求。虽然Session保存在服务器,对客户端是透明的,但它的正常运行仍然需要客户端浏览器的支持。这是因为Session 需要使用Cookie作为识别标志。因此服务器向客户端浏览器发送一个名为 JSESSIONID的Cookie,它的值为该 Session的ID。测试人员获取 JSESSIONID的值即可。
Session的有效期与会话有关。存储 JSESSIONID的Cookie是服务器自动生成的,它的maxAge 属性一般为—1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效,因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session,但是由浏览器窗口内的链接、脚本等打开的新窗口(不是双击桌面浏览器图标等打开的窗口)使用同一个Session。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。
新开的浏览器窗口会生成新的 Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,子窗注意
口便可以访问父窗口的Session。
那么,如果客户端浏览器将Cookie 功能禁用,或者不支持 Cookie 怎么办?例如,绝大多数的手机浏览器都不支持Cookie。对于Session的传输方法存在另一种解决方案:URL地址重写。
2.URL地址重写
URL地址重写是对客户端不支持Cookie的解决方案。它的原理是将该用户 Session的ID信息重写到URL地址中。服务器能够解析重写后的URL,获取Session的ID。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。
服务器代码会先自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出。如果客户端不支持Cookie,则会将用户Session的ID重写到URL中。重写后的输出可能是这样的。
https://mp.weixin.qq.com/s?jsessionid=ByoK3vjF7C2HmdnV6QZcEbzWoWiBYE-145
用户单击这个链接的时候会把Session的ID通过URL提交到服务器上,服务器通过解析URL地址获得Session的ID。
如果测试人员要构造特殊测试场景,需要获取非 Cookie 传输的Session,方法是要找开发人员帮忙获取 Session ID或者自行从服务端代码中获取。
Session的生命周期
在谈论Session 机制的时候,常常听到这样一种误解“只要关闭浏览器,Session就消失了”。 想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。 对 Session来说也是一样的,除非程序通知服务器删除一个Session,否则服务器会一直保留,程 序一般都是在用户做log off的时候发个指令去删除Session。然而浏览器从来不会主动在关闭之前 通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉, 是大部分 Session 机制都使用会话Cookie 来保存 Session ID,而关闭浏览器后这个 Session ID就消 失了,再次连接服务器时也就无法找到原来的Session。如果服务器设置的 Cookie 被保存到硬盘 上,或者使用模拟发包工具改写浏览器发出的请求头,把原来的Session ID发送给服务器,则再 次打开浏览器仍然能够找到原来的Session。
关闭浏览器不会导致Session被删除,迫使服务器为Seesion设置了一个失效时间,当距离客 户端上一次使用Session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动, 才会把 Session 删除,以节省存储空间。例如,Tomcat中Session的默认超时时间为20分钟,可 以通过 setMaxInactiveInterval(int seconds)方法修改 Session的默认超时时间。
Session与Cookie的区别
以上详解了关于Session的原理及基本概念,回看Cookie 章节发现Session与Cookie有着千 丝万缕的联系。在对测试人员关于接口方面的笔试与面试中,经常被问到Session与Cookie的区 别,答案总是千奇百怪,很少有人能够掌握充分,给出清晰的解答。以下就详细说一下这两者的 区别,给测试人员作为参考。
1.存储位置不同 通常情况
·Cookie的数据信息存放在客户端浏览器上。 Session的数据信息存放在服务器上。
2.存储容量不同 通常情况
·单个Cookie保存的数据≤4KB,一个站点最多保存20个Cookie。
·对于Session并没有上限,但出于对服务器端的性能考虑,Session内不要存放过多的东西, 并且设置 Session删除机制。
3.存取方式的不同
Cookie 中只能保管ASCII字符串,需要通过编码的方式存取Unicode 字符或者二进制数 据。运用Cookie 难以实现存储略微复杂的信息。
Session中能够存取任何类型的数据,包括且不限于String、Integer、List、Map等。
4.隐私策略的不同
Cookie 对客户端是可见的,别有用心的人可以分析存放在本地的 Cookie 并进行 Cookie欺骗,所以它是不安全的。
Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。
假如选用Cookie,比较好的方法是:敏感的信息,如账号密码等,尽量不要写到Cookie中。可以将 Cookie 信息加密,提交到服务器后再进行解密。存储在本地的Cookie 就需要自行加密了。
5.有效期上的不同
·在介绍Cookie的章节中提到,开发可以通过设置Cookie的属性,达到使Cookie 长期有效的效果。
由于Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的过期时间默认 为—1,只需关闭窗口该 Session就会失效,因而Session不能达到长期有效的效果。就算不依赖于Cookie,运用URL地址重写也不能完成,因为假如设置Session的超时时间过长,服务器累计的Session就会越多,越容易导致内存溢出。
6.服务器压力的不同
Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。
·Cookie 保管在客户端,不占用服务器资源。对于并发用户十分多的网站,Cookie 是很好的选择。
7.浏览器支持的不同
假如客户端浏览器不支持Cookie。
Cookie是需要客户端浏览器支持的。假如客户端禁用了Cookie,或者不支持Cookie,则会话跟踪会失效。关于WAP上的应用,常规的Cookie就派不上用场了。
运用Session需要使用URL地址重写的方式。一切用到Session程序的URL都要进行URL地址重写,否则Session会话跟踪还会失效。关于WAP应用来说,Session+URL地址重写或许是它唯一的选择。
假如客户端支持Cookie。
·Cookie 既能够设为本浏览器窗口以及子窗口内有效(把过期时间设为—1),也能够设为一切窗口内有效(把过期时间设为某个大于0的整数)。
Session 只能在本窗口以及其子窗口内有效。假如两个浏览器窗口互不相干,它们将运用两个不同的Session。(IE8下不同窗口Session相干。)
8.跨域支持上的不同
Cookie 支持跨域名访问,例如,将 domain 属性设置为“.biaodianfu.com”,则以 “.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。跨域名 Cookie 如今被普遍用 在网络中,例如,Google、Baidu、Sina等。
Session则不会支持跨域名访问。Session 仅在它所在的域名内有效。
关于Cache、Cookie与Session的知识是许多测试人员所忽视的内容,但这些运行机制往往就是请求能够被正确传输的最核心的内容,除了测试人员在执行测试任务时会运用到,其更是如何和开发人员有效沟通的技术基础。不要认为这些是开发基础就忽视它,必须做到知其然,并知其所以然。在掌握以上基础知识后,测试人员还需要了解由它们引出的Token和JWT。