摘自透视HTTP协议:让我知道你是谁:HTTP的Cookie机制
响应头字段 Set-Cookie
当用户通过浏览器第一次访问服务器的时候,服务器肯定是不知道他的身份的。所以,就要创建一个独特的身份标识数据,格式是key=value
,然后放进 Set-Cookie
字段里,随着响应报文一同发给浏览器。
浏览器收到响应报文,看到里面有 Set-Cookie
,知道这是服务器给的身份标识,于是就保存起来,下次再请求的时候就自动把这个值放进 Cookie
字段里发给服务器。
因为第二次请求里面有了 Cookie
字段,服务器就知道这个用户不是新人,之前来过,就可以拿出 Cookie
里的值,识别出用户的身份,然后提供个性化的服务。
不过因为服务器的“记忆能力”实在是太差,所以,服务器有时会在响应头里添加多个 Set-Cookie
,存储多个key=value
。
但浏览器这边发送时不需要用多个 Cookie
字段,只要在一行里用“;”隔开就行。

请求头字段 Cookie
Cookie
就是服务器委托浏览器存储在客户端里的一些数据,而这些数据通常都会记录用户的关键识别信息。所以,就需要在key=value
外再用一些手段来保护,防止外泄或窃取,这些手段就是 Cookie 的属性
。

首先,我们应该设置 Cookie 的生存周期
,即有效期
,可以使用 Expires
和 Max-Age
两个属性来设置。Expires
俗称过期时间
,用绝对时间点
,可以理解为截止日期deadline
。Max-Age
用相对时间
,单位是秒,浏览器用收到报文的时间点再加上 Max-Age
,就可以得到失效的绝对时间。它俩可以同时出现,两者可一致,也可不一致,但浏览器会优先采用 Max-Age
其次,我们需要设置 Cookie 的作用域
,让浏览器仅发送给特定的服务器和 URI
,避免被其他网站盗用。Domain
和Path
指定了 Cookie 所属的域名和路径
,浏览器在发送 Cookie
前会从 URI
中提取出 host
和 path
部分,对比 ,如果不满足条件,就不会在请求头里发送 Cookie
。
最后要考虑的就是 Cookie 的安全性
了,尽量不要让服务器以外的人看到。写过前端的同学一定知道,在 JS 脚本
里可以用 document.cookie
来读写 Cookie
数据,这就带来了安全隐患,有可能会导致跨站脚本XSS
攻击窃取数据。属性HttpOnly
会告诉浏览器,此 Cookie
只能通过浏览器 HTTP
协议传输,禁止其他方式访问,浏览器的 JS
引擎就会禁用 document.cookie
等一切相关的 API
,脚本攻击也就无从谈起了。
另一个属性SameSite
可以防范跨站请求伪造XSRF攻击
,设置成SameSite=Strict
可以严格限定 Cookie
不能随着跳转链接跨站发送,而SameSite=Lax
则略宽松一点,允许GET/HEAD
等安全方法,但禁止 POST
跨站发送。
还有一个属性叫Secure
,表示这个 Cookie
仅能用 HTTPS
协议加密传输,明文的 HTTP
协议会禁止发送。但 Cookie
本身不是加密的,浏览器里还是以明文的形式存在。
Chrome
开发者工具是查看 Cookie
的有力工具,在Network-Cookies
里可以看到单个页面 Cookie
的各种属性,另一个Application
面板里则能够方便地看到全站的所有 Cookie
。


Cookie 的应用
Cookie 最基本的一个用途就是身份识别
,保存用户的登录信息,实现会话事务。比如,你用账号和密码登录某电商,登录成功后网站服务器就会发给浏览器一个 Cookie
,内容大概是name=yourid
,这样就成功地把身份标签贴在了你身上。之后你在网站里随便访问哪件商品的页面,浏览器都会自动把身份 Cookie
发给服务器,所以服务器总会知道你的身份,一方面免去了重复登录的麻烦,另一方面也能够自动记录你的浏览记录和购物下单(在后台数据库或者也用 Cookie
),实现了状态保持
。
Cookie 的另一个常见用途是广告跟踪
。你上网的时候肯定看过很多的广告图片,这些图片背后都是广告商网站(例如 Google
),它会“偷偷地”给你贴上 Cookie
小纸条,这样你上其他的网站,别的广告就能用 Cookie
读出你的身份,然后做行为分析,再推给你广告。这种 Cookie
不是由访问的主站存储的,所以又叫第三方 Cookie(third-party cookie)
。如果广告商势力很大,广告到处都是,那么就比较“恐怖”了,无论你走到哪里它都会通过 Cookie
认出你来,实现广告“精准打击”。
为了防止滥用 Cookie
搜集用户隐私,互联网组织相继提出了 DNT(Do Not Track)
和 P3P(Platform for Privacy Preferences Project)
,但实际作用不大。
jsessionid
什么时候生成并传递到前端的?
- 如果客户端请求的
cookie
中不包含JSESSIONID
,服务端调用request.getSession()
时就会生成并传递给客户端,此次响应头会包含设置cookie
的信息

- 如果客户端请求的
cookie
中包含JSESSIONID
,服务端调用request.getSession()
时就会根据JSESSIONID
进行查找对象,如果能查到就返回,否则就跟没传递JSESSIONID
一样;
image.png
网友评论