一文搞懂Cookie

120 阅读6分钟

在实习的时候mentor总是说:没有八股,都是实践中得出的经验。

对于cookie这种面试高频八股,也是从实践中一步步学习得到的。

什么是cookie,COokie产生是为了解决是没问题?

如果说不想着方便人类的,那么就不会产生飞机,不会产生计算机,也就不会有一门门科学技术的进步。(说大话^_^)其实cookie 的出现也是为了方便人类的需求。 来看一下基于http 1.x 情况下通信会产生的问题:

  1. 第一步,用户登录并把商品加入到购物车
  2. 第二步,用户跳转到下单页面,由于http1.x的无状态性,用户登录状态失效,重新请求用户登录。

由以上两步就可以看出,用户在使用无状态http的时候就会一直被要求输入账号密码进行身份验证,因为服务器只有通过账号密码的方式来对用户进行身份验证。那用户体验是极其糟糕的。那么如何解决这个问题呢? 这里介绍两种方法

  1. 使用cookie携带用户的登录JWT(也可以使用自定义header来携带token信息),来对用户进行身份鉴权
  2. 使用cookie携带session来进行用户登录状态,来对用户进行身份鉴权。 我们可以发现,以上两种方式都是通过cookie为载体,来对用户进行状态验证。 我们可以使用chrome浏览器的F12状态下的Application来查看Cookie

image.png 接下来就来了解一下Cookie的具体内容

Cookie如何设置

Cookie是服务端通过http请求的Set-Cookie字段来对进行设置,简单来说就是以下几个步骤

  1. 客户端发送 HTTP 请求到服务器
  2. 当服务器收到 HTTP 请求时,在响应头里面添加一个 Set-Cookie 字段
  3. 浏览器收到响应后保存下 Cookie
  4. 之后对该服务器每一次请求中都通过 Cookie 字段将 Cookie 信息发送给服务器。

可以从响应头中看到Set-cookie的字段

image.png

那接下来就来重点学习一下Cookie的字段

image.png

Name

意如其名,就是Cookie字段的key

value

意如其名,就是Cookie字段的Value字段。包含这个Cookie所有携带的信息。

Domain

Domain 指定了 Cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)。 同一个父级域名下的Cookie是可以进行共享的

image.png 这些Cookie的Domain都是.poizonapp.com 那么在 dev.poizonapp.comprod.poizonapp.com下都是可以被共享的。 但是需要注意的是,如果我们在http://m.poizonapp.com 下把 Cookie的Domain设置成 .taobao.com,那么这个Cookie在.taobao.com下是无效的。换句话说,跨域设置的Cookie并不会在想要被访问的Domain下生效。

Path

访问url的具体path下的资源,这个Cookie才会生效

Expires / Max-Age

设置Cookie的过期时间,如果不进行设置,那么Cookie就会在Session关闭的时候被删除掉。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样。

Size

Cookie的大小,Cookie的最大容量是4kb

HttpOnly

为了防止XSS攻击,设置了这个属性为True的时候,Document.cookie 就不能访问到cookie。

Secure

标记为 Secure 的 Cookie 只应通过被HTTPS协议加密过的请求发送给服务端。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。

SameSite

SameSite 是最近非常值得一提的内容,因为 2 月份发布的 Chrome80 版本中默认屏蔽了第三方的 Cookie,这会导致阿里系的很多应用都产生问题,为此还专门成立了问题小组,推动各 BU 进行改造。

作用

我们先来看看这个属性的作用:

SameSite 属性可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。

属性值

SameSite 可以有下面三种值:

  1. Strict 仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致。
  2. Lax 允许部分第三方请求携带 Cookie
  3. None 无论是否跨站都会发送 Cookie

之前默认是 None 的,Chrome80 后默认是 Lax。

跨域和跨站

首先要理解的一点就是跨站和跨域是不同的。同站(same-site)/跨站(cross-site)」和第一方(first-party)/第三方(third-party)是等价的。但是与浏览器同源策略(SOP)中的「同源(same-origin)/跨域(cross-origin)」是完全不同的概念。

同源策略的同源是指两个 URL 的协议/主机名/端口一致。例如,https://www.taobao.com/pages/...,它的协议是https,主机名是 www.taobao.com,端口是 443。

同源策略作为浏览器的安全基石,其「同源」判断是比较严格的,相对而言,Cookie中的「同站」判断就比较宽松:只要两个 URL 的 eTLD+1 相同即可,不需要考虑协议和端口。其中,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1 则表示,有效顶级域名+二级域名,例如 taobao.com 等。

举几个例子,www.taobao.com 和 www.baidu.com 是跨站,www.a.taobao.com 和 www.b.taobao.com 是同站,a.github.io 和 b.github.io 是跨站(注意是跨站)。

Cookie 的作用

Cookie 主要用于以下三个方面:

  1. 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  2. 个性化设置(如用户自定义设置、主题等)
  3. 浏览器行为跟踪,采用埋点系统进行跟踪(如跟踪分析用户行为等)

Cookie 的缺点

如果被问到话,可以从大小、安全、增加请求大小等方面回答。

这就是关于Cookie的一些基础的介绍,接下来会介绍一些常用的面试题,帮助我们彻底攻克面试Cookie

Cookie、SessionStorage & LocalStorage的区别

Cookie如何进行身份验证,存在Cookie和localStorage有什么区别?为什么要存在localStorage? 为什么要存在Cookie?

为什么说Session是单次会话关闭就丢失了?Session一定会单次会话关闭就丢失了吗?

同一个源的两个页面会共享Cookie吗?不会的话如何让这两个页面共享Cookie?

跨域如何共享Cookie?

localStorage存满了怎么办?

Cookie用什么字段来限制跨域?

强缓存和协商缓存分贝是什么,有缓存的情况下请求过程是怎么样的?

XSS攻击和CSRF攻击,自己遇到过吗?如何解决