一文彻底搞懂cookie和session

为什么需要cookie和session

在Web发展史中,我们知道浏览器与服务器间采用的是http协议,而这种协议是无状态的,所以这就导致了服务器无法知道是谁在浏览网页,但很明显,一些网页需要知道用户的状态,例如登陆,购物车等。

所以为了解决这一问题,先后出现了四种技术,分别是隐藏表单域,URL重写,cookie,session。而用的最多也是比较重要的就是cookie和session了。

Cookie

首先来了解cookie

是什么

cookie是浏览器保存在用户电脑上的一小段文本,通俗的来讲就是当一个用户通过http访问到服务器时,服务器会将一些Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据通过请求头又被完整地给带回服务器,服务器根据这些信息来判断不同的用户。

也就是说,cookie是服务器传给客户端并保存在客户端的一段信息,这个Cookie是有大小,数量限制的!!

Cookie的创建

当前Cookie有两个版本,分别对应两种设置响应头:“Set-Cookie”和“Set-Cookie2”。在Servlet中并不支持Set-Cookie2,所以我们来看看Set-Cookie的属性项:

属性项 属性项介绍
NAME=VALUE 键值对,可以设置保存的Key/Value,这里NAME不能和其他属性项名字一样
Expires 过期时间,在这个时间点后Cookie失效
Domain 生成Cookie域名
Path 该Cookie是在当前那个路径下生成的
Secure 加密设置,设置他之后,只会在SSH连接时才会回传该Cookie

现在,我们先来了解这些属性项,其他的都说的很清楚了,我们来看看Domain有什么用:

现在,我们假设这里有两个域名:

域名A:a.b.f.com.cn
域名B:c.d.f.com.cn

显然,域名A和域名B都是f.com.cn的子域名

综上所述,我们知道了domain的用处,聪明的小伙伴已经发现了,单点登陆就是用这个原理实现的。

好的,现在了解完了Set-Cookie的属性项,开始创建Cookie

Web服务器通过发送一个称为Set-Cookie的http消息来创建一个Cookie:

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

这里我们思考一个问题,当我们在服务器创建多个Cookie时,这些Cookie最终是在一个Header项中还是以独立的Header存在的呢?

int size = headers.size();
for(int i = 0;i < size;i++){
    outputBuffer.sendHeader(headers.getName(i),headers.getValue(i));
}
复制代码
我们可以看到,构建http返回字节流时是将Header中所有的项顺序写出,而没有进行任何修改。所以可以想象在浏览器在接收http返回的数据时是分别解析每一个Header项。

++ 接着,在客户端进行保存,如何保存呢?这里又要对Cookie进行进一步的了解。 ++

Cookie的分类

会话级别Cookie:

所谓会话级别Cookie,就是在浏览器关闭之后Cookie就会失效。

持久级别Cookie:

保存在硬盘的Cookie,只要设置了过期时间就是硬盘级别Cookie。

好的,现在cookie保存在了客户端,当我们去请求一个URL时,浏览器会根据这个URL路径将符合条件的Cookie放在请求头中传给服务器。

Session

各位客官看到这里实属不易,😀,但我们还是要想想,Cookie是有大小限制和数量限制的,并且越来越多的Cookie代表客户端和服务器的传输量增加,可不可以每次传的时候不传所有cookie值,而只传一个唯一ID,通过这个ID直接在服务器查找用户信息呢?答案是有的,这就是我们的session。

理解Session:

Session是基于Cookie来工作的,同一个客户端每次访问服务器时,只要当浏览器在第一次访问服务器时,服务器设置一个id并保存一些信息(例如登陆就保存用户信息,视具体情况),并把这个id通过Cookie存到客户端,客户端每次和服务器交互时只传这个id,就可以实现维持浏览器和服务器的状态,而这个ID通常是NAME为JSESSIONID的一个Cookie。

Session和Cookie

实际上,有四种方式让Session正常工作

  1. 通过URL传递SessionID
  2. 通过Cookie传递SessionID
  3. 通过SSL传递SessionID
  4. 通过隐藏表单传递SessionID
第一种情况:

当浏览器不支持Cookie功能时,浏览器会将用户的SessionCookieName(默认为JSESSIONID)重写到用户请求的URL参数中。格式:/path/Servlet;name=value;name2=value2?Name3=value3

第三种情况:

会根据javax.servlet.request.ssl_session属性值设置SessionID。

注:如果客户端支持Cookie,又通过URL重写,Tomcat仍然会解析Cookie中的SessionID并覆盖URL中的SessionID

工作原理

我们先看session工作的时序图

一、创建Session

当客户端访问到服务器,服务器会为这个客户端通过request.getSession()方法创建一个Session,如果当前SessionID还没有对应的HttpSession对象,就创建一个新的,并添加到org.apache.catalina.Manager的sessions容器中保存,这就做到了对状态的保持。当然,这个SessionID是唯一的

二、session保存

由图可知,session对象已经保存在了Manager类中,StandardManager作为实现类,通过requestedSessionId从StandardManager的sessions集合中取出StandardSession对象。

我们来看看StandardManager时如何对所有StandardSession对象进行生命周期管理

当Servlet容器关闭:

StandardManager将持久化没过期的StandardSession对象(必须调用Servlet容器中的stop和start命令,不能直接kill)

当Servlet容器重启时:

StandardManager初始化会重读这个文件,解析出所有session对象。

三、session的销毁

这里有一个误区,也是我之前的错误理解,就是我将session的生命周期理解成一次会话,浏览器打开就创建,浏览器关闭就销毁,这样理解是错的!!

session的声明周期是从创建到超时过期

也就是说,当session创建后,浏览器关闭,会话级别的Cookie被销毁,如果没有超过设定时间,该SessionID对应的session是没有被销毁的

检查session失效

检查每个Session是否失效是在Tomcat的一个后台线程完成的(backgroundProcess()方法中);除了后台进程检验session是否失效外,调用request.getSession()也会检查该session是否过期,当然,调用这种方法如果过期的话又会重新创建一个新的session。

做个总结

相同点和不同点

相同点(有关系的地方)

  • Session和Cookie都是为了让http协议又状态而存在
  • Session通过Cookie工作,Cookie传输的SessionID让Session知道这个客户端到底是谁

不同点

Session将信息保存到服务器,Cookie将信息保存在客户端

工作流程

当浏览器第一次访问服务器时,服务器创建Session并将SessionID通过Cookie带给浏览器保存在客户端,同时服务器根据业务逻辑保存相应的客户端信息保存在session中;客户端再访问时上传Cookie,服务器得到Cookie后获取里面的SessionID,来维持状态。

作者:PatrickLee666
链接:https://juejin.im/post/5b7c1f4d6fb9a019f221ca14

求点赞,求关注~


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容