Session 实现原理

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

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

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    125 引用 • 74 回帖
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 406 关注
  • CAP

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

    12 引用 • 5 回帖 • 635 关注
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    118 引用 • 54 回帖 • 1 关注
  • Love2D

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

    14 引用 • 53 回帖 • 561 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 537 关注
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖 • 1 关注
  • 反馈

    Communication channel for makers and users.

    120 引用 • 906 回帖 • 280 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 439 关注
  • BAE

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

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

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

    12 引用 • 50 回帖 • 515 关注
  • CodeMirror
    2 引用 • 17 回帖 • 167 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 664 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 450 关注
  • 印象笔记
    3 引用 • 16 回帖
  • 黑曜石

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

    A second brain, for you, forever.

    24 引用 • 242 回帖
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 762 关注
  • Netty

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

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

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 491 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 342 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    93 引用 • 122 回帖 • 619 关注
  • 导航

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

    45 引用 • 177 回帖 • 2 关注
  • H2

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

    11 引用 • 54 回帖 • 671 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖 • 1 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 367 回帖
  • Anytype
    3 引用 • 31 回帖 • 27 关注