读书笔记:HTTP中的Session
Session来源
Session从原始意思上讲是会话,如果放在Web访问中,是指用户通过浏览器进入某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户与网站一次“会话”的时间。我们在这里介绍的Session是利用其定义来强调的一种保持用户访问状态的机制。
Session工作机制
Session机制是怎么实现的?
当用户A打开浏览器,输入URL向服务器发出请求时,服务器为这个用户分配了一个全局唯一的标识,称为SessionID,标识与这个用户的这次会话。这个Session ID可以保存在服务器的内存中,也可以写到文件里甚至数据库中,后者会增加每次读取Session ID的系统开销,但也能降低前者在停电或系统宕机情况下所带来的损失。
如果在服务器为用户A提供网页的同时,另一个用户B也打开浏览器请求服务器提供服务,服务器会再为用户B分配一个Session ID,这两个Session ID是不能相同的,通常服务器会使用散列函数为正在访问的不同用户产生各自的Session ID,尽最大可能确保各个ID的全局唯一性。
在为用户生成新的Session ID后,此Session ID会包含在响应消息中返回给浏览器。当用户下次访问服务器时就可以在请求中包含此Session ID,服务器将收到的Session ID与数据库或文件中保存的ID进行比较,如果匹配则可以获知用户以前访问的信息以及相关状态,否则将需要重新生成SessionID并返回给浏览器。
服务器将Session ID返回给浏览器的方法有以下两种:
- 一种是Cookie方法;
即采用HTTP协议中的Cookie机制来实现,服务器端产生Session ID后,通过Set-Cookie扩展头将Session ID传送到浏览器,而浏览器此后的每一次请求都会在Cookie头里带上这个ID。
- 另一种Session ID传送方法,叫URL重写。
由于Cookie可能被人为禁止,所以必须有其他机制以便在Cookie被禁止时仍然能够把Session ID传递回服务器。URL重写就是服务器在返回用户请求的页面之前,将页面内所有的URL后面附上Session ID,这样用户在收到响应之后,无论点击哪个链接,都会再带上Session ID,从而就实现了会话的保持。
URL重写的方式也有两种:
- 一种是作为URL路径的附加信息,表现形式为http://…/xxx;jsessionid=…;
- 另一种是作为查询字符串附加在URL后面,表现形式为http://…/xxx?jsessionid=…。
这两种方式对于用户来说是没有区别的,只是服务器在解析时的处理机制不同,采用第一种方式比较有利于把Session ID的信息和正常程序参数区分开来。
Session安全性
前面虽然提到Session的定义是用户访问某网站到关闭浏览器的会话时间,但在实际Web访问中,关闭浏览器并不意味着Session真正结束了,因为Session ID还会保存在服务器中。
要在服务器中清除Session ID的信息,需要浏览器主动发出一个结束Session的请求,比如点击网页上的“注销”、“退出”等链接,而很多用户一般都会在不想继续访问时直接关闭浏览器,所以Session ID在过期(服务器设置的一个时间)之前会作为一个隐患继续存在。
不管是采用Cookie的方式还是采用URL重写的方式,都有这种ID遗留问题,如果攻击者获取了Session ID,即使用户已经关闭了相关联的浏览器程序,他们仍然可以在请求中包含这个ID来访问服务器,获取用户的关键信息。
Session将与用户访问相关的敏感信息都保存在安全级别较高的服务器中,而不是用户机器上,所以像Cookie文件那样被窃取而导致信息丢失的风险大大降低。但是,与用Cookie来保持状态性一样,Session仍然会在请求和响应中出现SessionID信息,这个信息仍然可以被网络攻击者捕获到,并冒充用户欺骗服务器,进行中间人攻击。