Session 实现原理

本贴最后更新于 3034 天前,其中的信息可能已经物是人非

Session 实现原理

标签: sessionserverurlheaderwebhtml

分类:

web 开发_(9)_

Session 实现原理

2008-08-26 17:11

关键字: jsp,session

HTTP 协议 ( http://www.w3.org/Protocols/ )是“一次性单向”协议。
服务端不能主动连接客户端,只能被动等待并答复客户端请求。客户端连接服务端,发出一个 HTTP Request,服务端处理请求,并且返回一个 HTTP Response 给客户端,本次 HTTP Request-Response Cycle 结束。
我们看到,HTTP 协议本身并不能支持服务端保存客户端的状态信息。于是,Web Server 中引入了 session 的概念,用来保存客户端的状态信息。
这里用一个形象的比喻来解释 session 的工作方式。假设 Web Server 是一个商场的存包处,HTTP Request 是一个顾客,第一次来到存包处,管理员把顾客的物品存放在某一个柜子里面(这个柜子就相当于 Session),然后把一个号码牌交给这个顾 客,作为取包凭证(这个号码牌就是 Session ID)。顾客(HTTP Request)下一次来的时候,就要把号码牌(Session ID)交给存包处(Web Server)的管理员。管理员根据号码牌(Session ID)找到相应的柜子(Session),根据顾客(HTTP Request)的请求,Web Server 可以取出、更换、添加柜子(Session)中的物品,Web Server 也可以让顾客(HTTP Request)的号码牌和号码牌对应的柜子(Session)失效。顾客(HTTP Request)的忘性很大,管理员在顾客回去的时候(HTTP Response)都要重新提醒顾客记住自己的号码牌(Session ID)。这样,顾客(HTTP Request)下次来的时候,就又带着号码牌回来了。
我们可以看到,Session ID 实际上是在客户端和服务端之间通过 HTTP Request 和 HTTP Response 传来传去的。

我们看到,号码牌(Session ID)必须包含在 HTTP Request 里面。关于 HTTP Request 的具体格式,请参见 HTTP 协议(http://www.w3.org/Protocols/ )。这里只做一个简单的介绍。
Java Web Server(即 Servlet/JSP Server)中,Session ID 用 jsessionid 表示(请参见 Servlet 规范)。
HTTP Request 一般由 3 部分组成:
(1)Request Line
这一行由 HTTP Method(如 GET 或 POST)、URL、和 HTTP 版本号组成。
例如,GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
GET http://www.google.com/search?q=Tomcat HTTP/1.1
POST http://www.google.com/search HTTP/1.1
GET http://www.somsite.com/menu.do;jsessionid=1001 HTTP/1.1

(2)Request Headers
这部分定义了一些重要的头部信息,如,浏览器的种类,语言,类型。Request Headers 中还可以包括 Cookie 的定义。例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Accept-Language: en-us
Cookie: jsessionid=1001

(3)Message Body
如果 HTTP Method 是 GET,那么 Message Body 为空。
如果 HTTP Method 是 POST,说明这个 HTTP Request 是 submit 一个 HTML Form 的结果,
那么 Message Body 为 HTML Form 里面定义的 Input 属性。例如,
user=guest
password=guest
jsessionid=1001
主意,如果把 HTML Form 元素的 Method 属性改为 GET。那么,Message Body 为空,所有的 Input 属性都会加在 URL 的后面。你在浏览器的 URL 地址栏中会看到这些属性,类似于
http://www.fastfish/login.do?user=guest&password=guest&jsessionid=1001

从理论上来说,这 3 个部分(Request URL,Cookie Header, Message Body)都可以用来存放 Session ID。由于 Message Body 方法必须需要一个包含 Session ID 的 HTML Form,所以这种方法不通用。
一般用来实现 Session 的方法有两种:
(1)URL 重写。
Web Server 在返回 Response 的时候,检查页面中所有的 URL,包括所有的连接,和 HTML Form 的 Action 属性,在这些 URL 后面加上“;jsessionid=XXX”。
下一次,用户访问这个页面中的 URL。jsessionid 就会传回到 Web Server。
(2)Cookie。
如果客户端支持 Cookie,Web Server 在返回 Response 的时候,在 Response 的 Header 部分,加入一个“set-cookie: jsessionid=XXXX”header 属性,把 jsessionid 放在 Cookie 里传到客户端。
客户端会把 Cookie 存放在本地文件里,下一次访问 Web Server 的时候,再把 Cookie 的信息放到 HTTP Request 的“Cookie”header 属性里面,这样 jsessionid 就随着 HTTP Request 返回给 Web Server。

我们来看 Tomcat5 的源代码如何支持 jsessionid。
org.apache.coyote.tomcat5.CoyoteResponse 类的 toEncoded()方法支持 URL 重写。
String toEncoded(String url, String sessionId) {

StringBuffer sb = new StringBuffer(path);
if( sb.length() > 0 ) { // jsessionid can't be first.
sb.append(";jsessionid=");
sb.append(sessionId);
}
sb.append(anchor);
sb.append(query);
return (sb.toString());
}
我们来看 org.apache.coyote.tomcat5.CoyoteRequest 的两个方法 configureSessionCookie()
doGetSession()用 Cookie 支持 jsessionid.
/**

  • Configures the given JSESSIONID cookie.
  • @param cookie The JSESSIONID cookie to be configured
    */
    protected void configureSessionCookie(Cookie cookie) {

    }

HttpSession doGetSession(boolean create){

// Creating a new session cookie based on that session
if ((session != null) && (getContext() != null)
&& getContext().getCookies()) {
Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
session.getId());
configureSessionCookie(cookie);
((HttpServletResponse) response).addCookie(cookie);
}

}
Session 的典型应用是存放用户的 Login 信息,如用户名,密码,权限角色等信息,应用程序(如 Email 服务、网上银行等系统)根据这些信息进行身份验证和权限验证

1:Session 对象在浏览器中的有效范围:
IE 中:
1〉.Session 对象只在建立 Session 对象的窗口中有效。
2〉.在建立 Session 对象的窗口中新开链接的窗口也有效。
Session 只会在内存中,他会随着 IE 窗口的关闭而死亡。
也就是说单用 seesion 是不会有产生自动登入的效果的。
2:Cookie 是在服务器给客户端 IE 一个命令后在客户端产生并存的,
它可以存放用户信息,存到客户端硬盘上,在 COOKIE 记录被删除
或者失效日期之前,就可以实现自动登入的现象。
3:Session 和 Cookie 是不同的,但是他们确实是相关的。
当打开 IE 登入后,会向服务器发出一个指令请求 SESSIONID 以
及页面内容,服务器会返回页面内容和一个没有被使用的
SESSIONID 让此 IE 使用,当时 IE 就对返回 SESSIONID 做存储;而当此 IE 再访问任何这个站点的 JSP 程序的时候,都会给服务器这个 SESSIONID,来确认客户端的身份。(在没有 Cookie 的情况下 session 死亡 SESSIONID 被取消就需要重新登入)
4:可以通过客户端禁用和不禁用 cookie 来验证自己的说法。

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 233 回帖 • 1 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 735 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 87 关注
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖 • 3 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 828 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    198 引用 • 543 回帖 • 2 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 5 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 59 回帖 • 3 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    730 引用 • 1282 回帖 • 4 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 560 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    133 引用 • 796 回帖
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 678 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    45 引用 • 114 回帖 • 170 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 182 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 37 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    36 引用 • 200 回帖 • 31 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    151 引用 • 257 回帖 • 1 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 3 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    326 引用 • 1395 回帖 • 2 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 394 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    85 引用 • 324 回帖 • 2 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 121 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖