HTTP的Cookie机制

Cookie的工作过程

当用户通过浏览器第一次访问服务器的时候,服务器肯定不知道他的身份的。所以,就要创建一个独特的身份标识数据,格式是 “key=value”,然后放进Set-Cookie字段里,随着响应报文一同发给浏览器。

浏览器收到响应报文,看到里面有Set-Cookie,就知道这是服务器给的身份标识,于是就保存起来,下次请求的时候就自动把这个值放进Cookie字段里发给服务器。

因为第二次请求里面有了Cookie字段,服务器就知道这个用户不是新人,之前来过,就可以拿出Cookie里的值,识别出用户的身份,然后提供个性化的服务。

不过因为服务器的 “记忆能力” 实在是太差,一张小纸条经常不够用。所以,服务器有时会在响应头里添加多个 Set-Cookie,存储多个 “key=value”。但浏览器这边发送时不需要多个Cookie字段,只需要在一行里用 “;” 隔开就行。

img

从这张图中我们也能够看到,Cookie是由浏览器负责存储的,而不是操作系统。所以,他是”浏览器绑定“ 的,只能在本浏览器内生效。

如果你换个浏览器或者换台电脑,新的浏览器里没有服务器对应的Cookie,就好像时脱掉了贴着纸条的衣服,”健忘“ 的服务器也就认不出来了,只能再走一遍Set-Cookie 流程。

Cookie的属性

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

首先,我们应该设置Cookie的生存周期,也就是它的有效期,让他只能在一段时间内可用,就像是食品的“保鲜期”,一旦超时这个期限浏览器就认为时Cookie失效,在存储里删除,也不会发送给服务器。

Cookie的有效期可以使用Expires 和 Max-Age 两个属性来设置。

Expires” 俗称 “过期时间”,用的时绝对的时间点,可以理解为“截止日期”。“Max-Age” 用的时相对时间,单位时秒,浏览器用收到报文的时间点再加上Max-Age,就可以得到失效的绝对时间。

Expires 和 Max-Age 可以同时出现,两者的失效时间可以一致,也可以不一致,当浏览器会优先采用Max-Age计算失效期。

比如在这个例子里,Expires 标记的过期时间是“GMT 2019 年 6 月 7 号 8 点 19 分”,而 Max-Age 则只有 10 秒,如果现在是 6 月 6 号零点,那么 Cookie 的实际有效期就是“6 月 6 号零点过 10 秒”。

其次,我们需要“设置Cookie的作用域”,让浏览器仅发送给特定的服务器和URI,避免被其他网站盗用。

作用域的设置比较简单,“Domain” 和 ”Path“ 指定了Cookie所属的域名和路径,浏览器在发送Cookie前会从URI中提取出host和path部分,比对Cookie的属性。如果不满足条件,就不会在请求头里发送Cookie。

最后要考虑的就是”Cookie的安全性了“,尽量不要让服务器意外的人看到。

写过前端的同学一定知道,在JS脚本里可以用document.cookie来读写Cookie数据,这就带来了安全隐患,有可能会导致”跨站脚本“(XSS)攻击窃取数据。

属性 ”HttpOnly“ 会告诉浏览器,此Cookie只能通过浏览器HTTP协议传输,禁止其他方式访问,浏览器的JS引擎就会禁用document.cookie等一切相关的API,脚本攻击也就无从谈起了。

另外一个属性 ”SameSite“ 可以防范 ”跨站请求伪造“(CSRF)攻击,设置成 ”SameSite=Strict“ 可以严格限定Cookie不能随着跳转连接跨站发送,而”SameSit=Lax“ 则略宽松一点,允许GET/HEAD等安全方法,但禁止POST跨站发送。

还有一个属性叫 ”Secure“,表示这个Cookie仅能用HTTPS协议加密传输,明文的HTTP协议会禁止发送。但Cookie本身不是加密的,浏览器里还是以明文的形式存在。

Cookie的应用

现在我们回到最开始的话题,有了Cookie,服务器就有了 “记忆能力”,能够保存“状态”,那么应该如何使用Cookie呢?

Cookie最基本的一个用途就是身份识别,保存用户的登录信息,实现会话事务。

比如,你用账号和密码登录某电商,登录成功后网站服务器就会发给浏览器一个Cookie,内容大概是“name=yourid”,这样就成功地把身份标签贴在了你身上。

之后你在网站里面随便访问哪件商品的页面,浏览器都会自动把身份Cookie发送给服务器,所以服务器总会知道你的身份,一方面免去了重复登陆的麻烦,另一方面也能够自动记录你的浏览记录和购物下单(在后台数据库或者也用Cookie),实现了 “状态保持”。

Cookie的另一个常见用途就是广告追踪

你上网的时候肯定看过很多的广告图片,这些图片背后都是广告商网站(例如Google),他会“偷偷地” 给你贴上Cookie小纸条,这样你上其他地网站,别地广告就能能用Cookie读出你的身份,然后做行为分析,再推给你广告。

这种Cookie不是由访问地主站存储地,所以又叫 “第三方Cookie”。如果广告商势力很大,广告到处都是,那么就比较“恐怖”了,无论你走到哪里他都会通过Cookie认出你来,实现广告“精准打击”。

为了防止滥用Cookie搜集用户隐私,互联网组织相继提出了DNT(Do Not Track)和 P3P,但实际作用不大。

小结

  • Cookie 是服务器委托浏览器存储地一些数据,让服务器有了 “记忆能力”;
  • 响应报文使用Set-Cookie字段发送 “key=value” 形式的Cookie值;
  • 请求报文里用地Cookie字段发送多个Cookie值;
  • 为了保护Cookie,还要给他设置有效期、作用域等属性,常用的由Max-Age、Expires、Domain、HttpOnly等;
  • Cookie最基本的用途是身份识别,实现有状态的会话事务。