Session和Cookie的深入研究
作者:孙鑫 来源:http://www.sunxin.org
发布者:孙鑫
时间:2009-05-25 15:07:21
Session是一种服务器端技术,Session对象在服务器端创建,通常采用散列表来存储
信息,例如,Tomcat的Session实现采用HashMap对象来存储属性名和属性值。
Cookie是由Netscape公司发明的、用于跟踪用户会话的一种方式。Cookie是由服务器发送给客户的片段信息,存储在客户端浏览器的内存中或硬盘上,在客户随后对该服务器的请求中发回它。Session与Cookie的最大的区别是,Session在服务端保存信息,Cookie在客户端保存信息。为了跟踪用户的会话,服务器端在创建Session后,需要将Session ID交给客户端,在客户端下次请求时,将这个ID随请求一起发送回来。可以采用Cookie或URL重写的方式,将Session ID发送给客户端。在5.2.2节的基于Cookie的会话跟踪的例子中,当访问了Servlet后,关闭浏览器,再次打开浏览器访问Servlet时,可以看到开始了一次新的会话。如果我们同时打开两个浏览器,访问同一个URL,那么每一个浏览器进程都将开始一个新的会话,如图5-8所示。而在“使用Cookie的实例”中,当我们登录后,关闭浏览器,再打开浏览器,访问GreetServlet2时,直接出现了欢迎页面。然后我们同时打开两个浏览器,访问GreetServlet2时,也直接出现了欢迎页面。也就说,在5.2.2节的例子中,保存Session ID的Cookie在关闭浏览器后就删除了,不能在多个浏览器进程间共享。而在“使用Cookie的实例”的例子中,保存用户名和密码的Cookie在浏览器关闭后,再次打开,仍然存在,可以在多个浏览器进程间共享。通常,我们将用于会话跟踪的Cookie叫做会话Cookie,在Servlet规范中,用于会话跟踪的Cookie的名字必须是JSESSIONID,它通常保存在浏览器的内存中。在浏览器内存中的会话Cookie不能被不同的浏览器进程所共享。在网络上,很多人有一种错误的认识,认为以不同的方式打开浏览器窗口,或者使用其他的非IE浏览器就可以在不同的浏览器进程之间共享会话Cookie。下面,我们和读者一起看看这种错误认识是如何产生的。首先看看IE浏览器,启动Tomcat服务器,打开IE浏览器,访问5.2.2节中的例子程序,在地址栏中输入:http://localhost:8080/ch05/login,然后单击IE浏览器菜单栏上的“文件”→“新建”→“窗口”(也可以在浏览器窗口上按下Ctrl+N组合键)打开一个新窗口,分别刷新原窗口和新窗口,可以看到两个窗口中显示的Session ID是同一个。由实验可以看到,某些方式下打开的多个IE浏览器,可以共享内存中的Cookie,而另外一些方式打开的多个IE浏览器,则不能共享内存中的Cookie。再使用其他浏览器进行验证,发现有的浏览器(例如Mozilla FireFox)不管以什么方式打开窗口,都可以共享内存中的Cookie。由此,一个错误的结论就产生了:不同的浏览器对内存中的Cookie有不同的处理方式,有的浏览器(FireFox)可以在多个浏览器进程间共享会话Cookie,IE浏览器是否共享Cookie,要看浏览器打开的方式。笔者为什么会说上述结论是错误的呢?这是因为得出结论的人不了解进程的概念。读者在以上述方式打开两个IE浏览器窗口后(如果有其他的IE浏览器打开,请先关闭),同时按下Ctrl+Alt+Del组合键,选择“任务管理器”,切换到“进程”标签页,在“映像名称”下查找IEXPLORE.EXE,看看找到了几个IEXPLORE.EXE,是不是只有一个!那么这说明了什么?说明我们所看到的两个IE浏览器窗口实际上是属于同一个IE浏览器进程,难怪它们能共享内存中的会话Cookie。以其他方式打开一个IE浏览器,可以看到在“映像名称”下多了一个IEXPLORE.EXE进程,既然是两个IE浏览器进程的窗口,当然无法共享内存中的Cookie了。同样的道理,Mozilla FireFox不管以什么方式打开窗口,始终只启动了一个进程,既然这些窗口同属于一个进程,当然可以共享内存中的Cookie了。所以我们说,对于存储在内存中的Cookie,是不能被不同的浏览器进程所共享的。共享只能发生在同一个浏览器进程的不同窗口中(因为这些窗口共享同一个进程地址空间)。关于进程和线程的知识,读者可以参看相关的书籍。
对于保存在硬盘上的Cookie,因为是在外部的存储设备中存储,所以可以在多个浏览器进程间共享。有些人对Session的使用存在着一种误解,认为浏览器一旦关闭,Session就消失了。这是因为有的人看到,关闭浏览器后,再打开一个浏览器,就开始了一次新的会话,从而得出了结论。再回头看看第5.1节中的顾客在超市存包的例子,顾客存好包,购物完毕,忘了取包就走了,但存包处的管理员不知道顾客已经走了,所以他必须继续用柜子(相当于Session)存放顾客的物品,直到长时间没有人来取(Session的超时值发生),管理员才清除柜子。之所以会有“浏览器一旦关闭,Session就消失了”这种错误的认识,主要是因为保存Session ID的Cookie是存储在浏览器的内存中,一旦浏览器关闭,Cookie将被删除,Session ID也就丢失了。当再次打开浏览器连接服务器时,服务器没有收到Session ID,当然也就无法找到先前的Session,于是服务器就创建了一个新的Session。而这个时候先前的Session是仍然存在的,直到设置的Session超时时间间隔发生,Session才被服务器清除。如果我们将会话Cookie保存到硬盘上,或者通过某种技术手段改写浏览器向服务器发送的请求报头,将原先的Session ID发送给服务器,则再次打开的浏览器就能够找到原来的Session了。 我们想了解一下,用于会话跟踪的Cookie是如何创建的,为何只能保存在浏览器的内存中,而不能保存到用户的硬盘上。在Tomcat 6.0.16.中,Session的创建是调用org.apache.catalina.connector.Request类中的doGetSession()方法来完成的。下面我们给出这个方法的代码片段: Java代码
1.protected Session doGetSession(boolean create)
2.{
3. …
4. // Creating a new session cookie based on that session
5. if ((session != null) && (getContext() != null)
6. && getContext().getCookies())
7. {
8. Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
9. session.getIdInternal());
10. configureSessionCookie(cookie);
11. response.addCookieInternal(cookie);
12. }
13.
14. if (session != null)
15. {
16. session.access();
17. return (session);
18. }
19. else
20. {
21. return (null);
22. }
23.}
24.
25.protected void configureSessionCookie(Cookie cookie)
26.{
27. cookie.setMaxAge(-1);
28. String contextPath = null;
29. if (!connector.getEmptySessionPath() && (getContext() != null))
30. {
31. contextPath = getContext().getEncodedPath();
32. }
33. if ((contextPath != null) && (contextPath.length() > 0))
34. {
35. cookie.setPath(contextPath);
36. }
37. else
38. {
39. cookie.setPath("/");
40. }
41. if (isSecure())
42. {
43. cookie.setSecure(true);
44. }
45.}
代码的第8行,我们看到非常熟悉的创建Cookie对象的代码,Cookie的名字是Globals.SESSION_ COOKIE_NAME,SESSION_COOKIE_NAME被定义为静态的常量,其值为JSESSIONID。Cookie的值是调用session.getIdInternal ()得到的Session ID。第10行,调用了configureSessionCookie()方法来配置会话Cookie。我们转到configureSessionCookie()方法中,第27行,调用Cookie对象的setMaxAge()方法设置Cookie的生存时间,在“使用Cookie的实例”的例子中,我们说过,如果时间值为负数,那么当客户端的浏览器退出,Cookie将会被删除。看到这儿,我们就知道了为什么会话Cookie只能保存在内存中了,这是由Tomcat的实现决定的。第35行,调用Cookie对象的setPath()方法,指定这个Cookie在当前Web应用程序的上下文路径下有效。学习方法:我们在学习的时候,不仅要通过实验来掌握知识,更重要的是要思考、理解实验结果产生的原因,从现象看本质,这样才不至于得出错误的结论。然而,由于我们所掌握的知识是有限的,有时候又难免犯这样或那样的错误,这不要紧,关键是要养成学习与思考的习惯,这样才能获得更大的进步。
分享到:
相关推荐
在IT安全领域,尤其是网络安全竞赛CTF(Capture The Flag)中,session管理是至关重要的一个环节。...通过研究和使用这个工具,我们可以深入了解session管理、加密技术以及如何在Python的Flask框架中实施安全策略。
本文将深入探讨`Flask`中的`session`和`cookie`,以及如何对它们进行解密。 首先,`session`和`cookie`都是用于跟踪用户状态的方法。`cookie`通常存储在用户的浏览器中,而`session`数据则保存在服务器端。`cookie`...
在ASP.NET中,Application、Session和Cookie是三个非常重要的概念,它们主要用于管理...通过实践和研究"Demo10-Application,Session,cookie.rar"中的示例,开发者能够更深入地理解这些概念,并将其应用到自己的项目中。
本压缩包提供的"PHP开发漏洞环境"是一个专门用于学习和研究这些安全问题的实践平台,包括SQL注入、文件上传、文件下载、XSS跨站脚本攻击、万能密码攻击以及session和cookie管理等多个方面。 1. SQL注入:这是一种...
【session简介】 在Web开发中,session是一种关键的技术,用于在客户端和服务器之间保持状态。本文将深入探讨session的工作原理,以及在Java Web应用程序中如何有效地利用...4. 《Cookie与Session机制比较研究》
在IT行业中,Session管理是Web应用中的重要环节,它用于在服务器端存储用户会话信息,...通过对"redissession共享代码"的深入研究和实践,开发者可以掌握这一技术,并将其应用到实际项目中,提升用户体验和系统稳定性。
在IT行业中,浏览器的Session管理是一个非常重要的概念,特别是在Web应用程序的设计和开发中。...在实际项目中,结合标签"源码"和"工具",可能还需要深入研究相关代码实现和利用调试工具进行问题定位。
对这些文件进行深入研究,可以帮助开发者更好地理解和实施跨域Session共享。 总结来说,C#不同域名之间的Session共享是一个重要的技术挑战,但通过理解各种策略和工具,我们可以有效地解决这个问题,提供无缝的用户...
通过对源代码的学习,我们可以更深入地理解session购物车的实现细节,包括如何在服务器端存储和操作购物车数据,以及如何在客户端与服务器之间传递session ID。 总之,session购物车是Web开发中实现用户购物功能的...
本文将深入讲解如何在Connect中使用session和cookie。 首先,让我们了解session和cookie的基本概念。Session是一种在服务器端存储用户状态的方法,它可以跨多个请求保持用户数据。而cookie是存储在客户端浏览器上的...
在IT领域,尤其是在Web开发中,Session Cookie和用户身份...在提供的文件"Session_Cookie_-thuc_hanh-luu_ten_nguoi_dung_Cookie-master"中,可能包含了关于这个话题的示例代码和教程,你可以进一步研究以加深理解。
深入研究Nginx的源码,了解其负载均衡算法和Session管理机制。 #### 五、总结 通过上述实战演练和源码透析的过程,我们可以深刻理解分布式环境下Session管理的关键技术和挑战。针对不同场景选择合适的Session管理...
.NET Session共享是Web应用程序在...通过深入研究这些文件,开发者可以学习如何在.NET环境中实现分布式环境下的Session共享,提升系统的可扩展性和可用性。同时,这也是理解和应用分布式系统设计原则的一个实践案例。
从创建、存储到读取,以及如何在不同编程环境中实现,再到安全性和生命周期管理等方面,Cookie都是一个值得深入研究的话题。希望本文能够帮助读者更好地理解Cookie的工作原理及其在实际开发中的应用。
你可以下载并研究这些文件,以更深入地理解这一技术实现。 总结来说,JavaScript 和 Cookie 的结合提供了一种轻量级的客户端购物车解决方案,允许用户在无服务器状态保持的情况下也能拥有持久的购物体验。然而,...
在Laravel框架中,Cookie和CSRF(Cross-Site Request Forgery,跨站请求伪造)是两个关键的安全概念...通过深入研究这个示例项目,开发者可以更好地理解和实践Laravel中的Cookie和CSRF保护策略,从而提升应用的安全性。
【标题】基于JSP动态登陆,注册的网站 cookie统计信息 ...本项目涉及到的关键知识点包括JSP、脚本语言(SCRIPT)、HTML、Cookie、...通过深入研究这个项目,你可以更好地理解Web应用的工作原理,并提升实际开发技能。
通过解压并打开 "cok.doc",我们可以深入学习和理解Cookie这一重要的网络技术,以及如何在日常浏览和开发工作中有效地处理和利用它们。同时,这也可能是一个了解当前隐私保护趋势和最佳实践的好资源。