Session 实现原理

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

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 来验证自己的说法。

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 405 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 473 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1398 回帖 • 1 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 8 关注
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 28 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    273 引用 • 679 回帖 • 1 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    10 引用 • 85 回帖
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 36 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    205 引用 • 357 回帖 • 1 关注
  • 微信

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

    129 引用 • 793 回帖 • 1 关注
  • 安全

    安全永远都不是一个小问题。

    189 引用 • 813 回帖 • 3 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 642 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    51 引用 • 226 回帖
  • 面试

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

    324 引用 • 1395 回帖 • 2 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    84 引用 • 139 回帖
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 372 关注
  • BND

    BND(Baidu Netdisk Downloader)是一款图形界面的百度网盘不限速下载器,支持 Windows、Linux 和 Mac,详细介绍请看这里

    107 引用 • 1281 回帖 • 22 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖 • 3 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    76 引用 • 421 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 602 关注
  • sts
    2 引用 • 2 回帖 • 147 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 399 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 605 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 17 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    21 引用 • 58 回帖 • 1 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 618 关注