Session 实现原理

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

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

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • BND

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

    107 引用 • 1281 回帖 • 37 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    6 引用 • 14 回帖
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    410 引用 • 1246 回帖 • 587 关注
  • 导航

    各种网址链接、内容导航。

    42 引用 • 175 回帖
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    230 引用 • 1454 回帖 • 1 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 484 关注
  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖
  • CSS

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

    196 引用 • 540 回帖 • 1 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    546 引用 • 672 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 614 关注
  • H2

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

    11 引用 • 54 回帖 • 656 关注
  • JavaScript

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

    728 引用 • 1275 回帖
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖 • 1 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 140 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    190 引用 • 1057 回帖
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    107 引用 • 295 回帖
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    946 引用 • 943 回帖 • 2 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 221 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 2 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 623 关注
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 465 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 41 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    5 引用 • 107 回帖 • 1 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    126 引用 • 169 回帖
  • Dubbo

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

    60 引用 • 82 回帖 • 604 关注