senline

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最近几天,在和同事讨论sso 和 微信认证集成的方案。讨论过程中,发现有的对http协议和web应用中客户端如何维持会话等问题认识不清楚,一是没做过,不了解,或者虽然做过,但是不知道为什么需要这么做,知其然不知其所以然。所以写这么一篇短文说说这个事情。这算是老生常谈了,网上有非常多,也非常好的文章,也可以百度来看。

现在的应用都可以理解为cs架构的。c是客户端,s是服务端。c发出请求,s给出响应。比如我们用ops做的系统,公司的内控,网站等等,这是一类很明显的应用,更泛化一点说,只要是两个端互相通讯,都可以抽象为c/s的关系。比如一个系统给另一个系统通过api传送数据。

C 和 S之间通讯,有各种协议,http协议就是最常用的一种。我们做的系统大多是这样的。我这里不讲http协议的细节,只讲一点,就是用http协议的时候,C 和 S之间怎么维持一个会话。

所谓会话(session),是指c 和 s之间为了完成一件事情,进行的一系列的通讯往来。一般不是一个来回,而是多个来回,持续的时间也会比较长。举个例子,登录系统,创建报销单,保存,提交,退出系统。这就是一个完整的会话。

大家知道,http协议一个典型的特定就是无状态,非持续连接的。啥意思呢,就是,http协议在通讯之前,建立c 和 s之间的连接,数据发送完毕,连接就断开了,这是非持续连接的意思;无状态的意思就是,两次通讯之间,没有任何关系,是独立的。具体一点就是,你登录京东网站,你连着看了两件商品,如果京东不采取点措施,它不知道这两次商品浏览是同一个人。如果是这样,网上购物根本就没法实现。因为选商品,支付要需要很多环节,需要N多次通讯才能完成,网站必须要知道着一系列的操作都属于一个会话,电脑这端是同一个人。

为便于理解,我举个现实中的例子,车站售票处(窗口很小,而且是不透明玻璃,里外看不到的那种),一堆人挤在外边问这问那。【1】你:B911班车到了吗?售票员:没有;【2】乘客甲:到济南多少钱?售票员:50元;【3】你:大约多久到?售票员:你问的那趟车啊?。 对售票员来讲,这3次问答(通讯)没有任何关联。售票员不知道是【1】和【3】是和同一个人对话。
后来,车站进行了改善,咨询前,先领一个号。每次咨询前,要报号。对话是这样的:
【1】你:B911班车到了吗?售票员:没有,来,给你个号,1号;【2】乘客甲:到济南多少钱?售票员:50元,你没领号啊,你是2号;【3】你:1号问个问题,大约多久到?售票员:B911大约1小时到。【4】乘客甲:2号问个问题,快车还是慢车啊?售票员:快车,慢车40元。
这样改进后,【1】和【3】这两次对话,就属于一次会话了,第二次问的时候,售票员知道你问的是B119次车。

其实浏览器访问网站,也采用了类似的解决方法,来识别每次访问的身份。
上面我说jd不知道两次访问是同一个人,严格讲是不准确的,其实它是知道的,即便你不登录。你可以试试,你在不登录的情况下,你放两个商品到购物车,购物车里确实会有两个商品。它是怎么做到的?

通过IP地址识别?因为你连续的两次操作都是使用的同一台电脑,IP不会变。这样可靠吗?不可靠,如果你在局域网内访问外网,服务器得到的ip并不是你机器的ip,而是局域网连接互联网的出口ip,所有在局域网内的机器的出口ip都是一样的。你可是试试换个浏览器访问jd,看购物车里是没有内容的。

Cookie!
其实浏览器使用的是cookie。
(Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明,Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie,百度百科)
cookie是服务器存放到你的机器上的数据。怎么存,如何存,是http协议的一部分,所有浏览器都支持的约定。每各cookie是 kv 的形式,还有有效期。浏览器除了能保存cookie之外,还有一个很关键的特点:它在每次访问服务器的时候,会自动把该网站存在你本地的所有cookie 发给服务器。
说道这里,大家肯定都明白了,http协议通过什么,或者说应用是通过什么来保持会话的。再说的细一点,我们捋一下。
(1)当你第一次访问jd,京东服务器会传给浏览器一个cookie,假设名字是 anyuser=<GUID>,同时在服务器内存中创建一块区域(我们称它为sessiom),和这个cookie的值关联。以后每次访问,浏览器都会把 anyuser=<GUID>发给服务器,服务器根据这个cookie的值,就知道你(严格来说是同一个电脑的同一个浏览器)先前是不是访问过jd,并通过它找到上面说的session里的内容。
(2)你放一个商品到购物车,jd后台,把这个商品存到session中。
(3)你再放一个商品到购物车,jd后台再把商品放进session中,这时购物车有2个商品了
(4)你查看购物车,jd从session中查询,展示给你2个商品。

以上就是cookie发生作用的原理和过程。
如果你随后清除掉jd网站下的cookie后,再看看购物车,空了!

我们再讲另外一个与cookie有关的,在web应用中举足轻重的东西:Session。

前面一直提到会话,英文是session,这是一个概念,表示从你开始对话,到最后结束对话的这段时间。对应到我们的系统,就是你从登陆系统到退出系统这段时间。

会话期间总要保存点什么把,会话这个概念在我们的应用的具体实现上,有个东西相对应,就是服务端的Session,Session类和实例。在应用服务器上,当你登陆了系统后,在创建一个cookie的同时(jsp应用中这个cookie的key一般是jsessionid),还会给你创建一个Session实例,保存你会话期间的一些信息,比如这个会话是属于哪个账号,会话开始时间等等。你也可以在Session里存放任何数据。

有同事可能说,我后台代码没有创建jsessionid 这个cookie,也没有创建session,取session里的值时,也没有用到jsessionid 啊,那是因为java底层框架把这些细节都给你做了(没写过java程序,不确定是这样的,我只知道.net是这样的。了解的同事补充下)

总结下Cookie 和会话的关系:
1,Cookie(KEY:JSessionID)是维持会话的唯一标识

2,SessionID 和 服务端 Session 是一一对应的

讲到这里就差不多了,系统登录过程中,甚至在SSO中,cookie的作用,我就不讲了。

还有如果浏览器禁止cookie怎么应对,cookie的作用域,也就是跨域问题,有效期,session的各种保存方式等等,都很容易理解,自己都可以查。

posted on 2019-10-17 14:33  森蓝2010  阅读(258)  评论(0编辑  收藏  举报