HTTP Session 的工作原理以及几个思维扩展

转载 2018年04月17日 11:00:52
无状态的 HTTP

大家都知道,我们目前使用的互联网应用层协议基本上都是基于 HTTP 和 HTTPS 的,它们的本身是无状态的, 只负责请求和响应。 我告诉服务器我需要什么,服务器返回给我相应的资源。 如果没有额外处理的话, 服务器是不知道你是谁,更无法根据你是谁给你展现和你相关的内容了。

HTTP 协议一开始被设计成这样还是有一些历史原因的,当时的互联网多用于学术交流,只用于文章信息的展现之类的事情,远没有现在这么丰富多彩。所以在当时的背景下 HTTP 协议被设计成这样其实也是很符合它的场景的。

但随着互联网应用越来越广泛,应用的形式也变得越来越多,我们的 Web 应用不只限于提供简单的信息展现了,还需要用户能够登录,可以在论坛发帖子,在购物网站买东西等等。 这就需要 HTTP 协议能够记录用户的状态。也就是我们现在熟悉的 Session 由来。

Session 如何实现

大多数 Web 框架都提供了操作 Session 的 API。 如果你有 Web 端开发的经验,那么你对这样的代码应该不会陌生:

session["name"] = "xxx";

我们给 session 对象设置一个值,比如用户登录成功后,给他设置一个用户名,这样我们这个用户的状态就保存下来了。 并且后续的请求中,这个状态都可以读取到。这一切就这么自动的发生了,并且习以为常。那么这一行代码背后发生了什么呢? 就是下面几个步骤。

生成 Session ID

关于 Session 的工作原理, 其实还是值得我们了解一下的。 我们调用上面这行代码后,我们使用的 Web 框架首先会给当前请求创建一个 Session ID。 这个 Session ID 是通过一系列算法生成的一个唯一字符串。 这也是一个 Web 框架(PHP, Ruby on Rails, ExpressJS 等)提供的基础能力,每个框架生成 Sesssion ID 的具体实现算法可能有所差别,但整体流程都是一样的。

建立服务端 Session 存储结构

这个新生成的 Session ID 用于标识这次发起请求的用户,并存储到服务器的某个区域中(默认情况下会在内存中)。 这个 Session ID 同样也是本地存储的一个 key,比如我们上面代码中设置了 name 属性,就相当于在这个 key 中设置了对应的属性。 这样说起来可能有点抽象,举个例子 Session 在服务端的存储结构大概相当于这样:

{
"session-id-1": {
"name" : "xxx"
},
"session-id-2": {
"name" : "xxx"
}
//...
}
}

服务端会保存这样一个字典, 将每个用户的 Session ID 和对应的属性都记录下来。

把 Session ID 返回给用户浏览器

还继续我们刚才的流程,生成完 Session ID 并建立好本地存储结构后, 服务端会在返回给用户的 HTTP 响应消息中带上这个 Session ID:


如上图, 通过 Response Header 的 set-cookie 带上,这样截图使用的是基于 Express 的 NodeJS 服务端框架, 这里面的 connect.sid=xxx 就是服务端给这个用户生成的 Session ID。

这样,用户的浏览器得到这个 Cookie 后,再下一次请求同一个网站的时候就会在请求中带上这个 Cookie。

如果你对 Cookie 的细节不熟悉的话,不用多想,你可以理解成这样 — 你用的所有浏览器都会有这个逻辑,收到 set-cookie 响应头后,就会把里面的内容保存下来,下一次再访问同样的站点时候,就会把之前保存的 cookie 再重新发送回去。当然,关于 Cookie 的细节还有很多知识,不过理解我的这个简单解释就足够了,感兴趣的话可以再深入研究。

客户端发送 Session ID

就会像我们刚说的,浏览器下一次再请求这个网站时,会把之前保存的 Session ID 再重新发给服务端。 这时候服务端就会用这个 Session ID 和它之前建立的存储结构中进行匹配,如果这个 Session ID 是之前合法创建的,那么就可以从服务端存储中得到用户之前的状态了,比如登录用户名之类的。 比如:

{
//...

"session-id-1": {
"name" : "xxx"
}

//...
}

假设上面是我们服务端建立的本地 Session 数据存储,如果 Session ID 正确匹配,就能找到对应这个用户的 name 属性了。

整体步骤

上面给大家介绍的就是 Session 整体的工作过程。 大概分为这几个步骤:

  1. 浏览器第一次请求网站, 服务端生成 Session ID。
  2. 把生成的 Session ID 保存到服务端存储中。
  3. 把生成的 Session ID 返回给浏览器,通过 set-cookie。
  4. 浏览器收到 Session ID, 在下一次发送请求时就会带上这个 Session ID。
  5. 服务端收到浏览器发来的 Session ID,从 Session 存储中找到用户状态数据,会话建立。
  6. 此后的请求都会交换这个 Session ID,进行有状态的会话。
扩展知识

看完这一套流程后,是不是对我们开始的那一行代码背后发生的事情了解的更通透了呢。还有几个值得讨论的地方也和大家聊聊。

1. Session ID

首先就是 Session ID,如果你理解了前面的介绍后,就会得到一个知识,在整个会话过程中,最重要的就是 Session ID。一个相对成熟的 Web 应用,往往会同时处理成百上千,甚至更大量的用户同时在线。 这就对 Session ID 的创建有一个非常重要的要求,那就是在保证生成性能的同时,不能重复!

可以想象,如果你的 Web 框架在生成 Session ID 的时候重复了,会发生什么事情 — 用户会误登录进别人的账号, 这个后果还是非常严重的。 好在现在成熟的 Web 框架都考虑到了这个问题,你知识框架的使用者,所以你不必过于担心。但了解背后的这个原理以及思维方式还是有助于你写出更安全的程序的。

2. Session 数据存储

另外一个要聊聊的就是 Session 数据的存储。 通常情况下,如果你不明确的设置, 大多数 Web 框架会把 Session 数据存放到内存中。如果你的 Web 应用用户量不大的话,这也不成问题。 但如果你的用户数比较大的话,就可能发生一个事情 — 内存不够用了。

这很正常,内存容量是非常宝贵的,假设每个用户的 Session 数据是 100K, 1万个用户就会大概占用 1G 的存储空间,如果你的 Session 数据清理机制也恰巧比较慢的话,内存非常容易被占满。

这就需要你在设计比较大并发量的站点时,要考虑 Session 的存储方式,比如把它们保存到硬盘文件系统中,或者数据库中。 所以你在开发一个 Web 应用的时候,如果你的用户量很大,你需要有这个意识。

另外 Session 放到内存中还有一个弊端,如果你的 Web 服务器发生重启,那么所有的 Session 状态都会被情况,会在一定程度上影响用户体验。

3. 传输安全

最后再聊聊传输安全,有一种叫做 Session ID 劫持的,假如 Session ID 是基于 HTTP 协议传输的,因为是明文传输,那么它就可能被中间的路由器劫持。 攻击者得到 Session ID 后,把它带到自己的请求中,就能够进入你的账户。

所以一些 Web 框架还提供了 Session 的一些安全保护,比如间隔时间内动态刷新 Session ID,加上 Token 等。但这些也无法完全保证不被中间人看到。 其实从这个角度也间接体现了为什么 HTTPS 这么重要。

总结

这次跟大家聊了一下 HTTP Session 的原理和整个工作过程。 透过对它的了解,不仅是对细节的掌握,更重要的是这些知识能够帮助我们理清对技术整体的思维方式。 包括我们最后说的 Session ID 生成机制。为什么把 Session 放到内存中会有问题,这样才会理解框架为什么要提供硬盘和数据库之类的其他 Session 存储方式。无论你使用什么框架,什么语言,这些原理性的东西都是不变的。了解的多了,你也就越来越不用焦虑学哪种技术有前途这个问题了。


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~ 

本站文章均为原创内容,如需转载请注明出处,谢谢。

初级汇编语言及计算机工作原理

在<计算机发展历史>的基础上,我们继续学习初级汇编语言以及简单的计算机工作原理知识.
  • 2017年03月24日 16:28

简单谈谈session机制的原理

做过web开发相信都对session这玩意挺熟悉的,今天无意间看到了篇讲session文章,自己也总结一下以此迎新年吧。 通常session机制可以借助cookie来实现,如果cookie被客户端禁止...
  • saylessanddomore
  • saylessanddomore
  • 2014-12-31 17:53:32
  • 1281

Cookie和Session的作用和工作原理

一、Cookie详解 (1)简介 因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒...
  • guoweimelon
  • guoweimelon
  • 2016-03-14 16:18:59
  • 9900

HTTP协议及工作原理

一 什么是HTTP协议? HTTP就是我们平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全。为了保证这些隐私数据能加密...
  • dengfan666
  • dengfan666
  • 2017-09-24 17:24:02
  • 372

PHP之session机制和优化

本文说一说PHP中的Session机制和优化的话题。默认情况下,我们是直接使用$_SESSION来操作会话,并且以文件的形式保存,一个会话对应一个文件。如果单个目录下存储太多会话文件影响读取效率,可以...
  • rariki
  • rariki
  • 2016-07-14 00:15:37
  • 1685

Cookie和Session的原理

Session是什么     Session一般译作会话,牛津词典对其的解释是进行某活动连续的一段时间。从不同的层面看待session,它有着类似但不全然相同的含义。比如,在web应用的用户看来...
  • Sup_Heaven
  • Sup_Heaven
  • 2014-09-21 21:23:08
  • 3284

Session 工作原理

session的工作原理 一、术语session 在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含义是...
  • kgd1120
  • kgd1120
  • 2008-03-09 11:42:00
  • 7579

高扩展Web应用HTTP Session共享方案

在构建能够灵活地进行水平扩展、高可用性的Java Web应用程序时候,对http session的处理策略很大程度决定了应用程序的扩展性、可用性。一般而言对http session有如下的处理方案: ...
  • u010282707
  • u010282707
  • 2014-07-07 22:57:10
  • 1199

Cookie和Session的作用,区别和各自的应用范围,cookie、Session工作原理

一、cookie机制和session机制的区别   具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。   同时我们也看到,由于在服务器端保...
  • wplblog
  • wplblog
  • 2016-07-18 07:37:36
  • 3777

HTTP Session和Cookie工作原理

session的工作原理  术语session  在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下...
  • bigtree_3721
  • bigtree_3721
  • 2016-02-15 02:01:08
  • 391
收藏助手
不良信息举报
您举报文章:HTTP Session 的工作原理以及几个思维扩展
举报原因:
原因补充:

(最多只允许输入30个字)