秋招复习计划-Cookie相关

  |  

前言

了解Cookie,以及最近的变动


68


HTTP

HTTP1.x是一个无状态协议,及同一个客户端连续发送两次请求到服务器,服务器也无法识别这是同一个客户端发送的请求。所以为了使服务器能识别用户身份,提出了Cookie

Cookie的提出并不是为了解决通信协议的无状态问题,而是为了解决客户端与服务器之间会话状态保持的问题,这个状态是指后端服务的状态而非通信协议的状态。

Cookie是指某些网站为了辨别用户身份而存储在用户本地终端上的数据。一般不超过4KB,只要由一个名称,一个值和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性。

Cookie的设置

Cookie设置的步骤:

  • 客户端发送HTTP请求到服务器
  • 服务器收到HTTP请求,在响应头里添加Set-Cookie字段
  • 浏览器收到响应后保存Cookie
  • 之后对该服务器的每一次请求都会通过Cookie字段将Cookie信息发送给服务器

Cookie属性

Name/Value

用 JavaScript 操作 Cookie 的时候注意对 Value 进行编码处理。

Expires

Expires 用于设置 Cookie 的过期时间。比如:

1
2
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
复制代码

当 Expires 属性缺省时,表示是会话性 Cookie,像上图 Expires 的值为 Session,表示的就是会话性 Cookie。当为会话性 Cookie 的时候,值保存在客户端内存中,并在用户关闭浏览器时失效。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样。

与会话性 Cookie 相对的是持久性 Cookie,持久性 Cookies 会保存在用户的硬盘中,直至过期或者清除 Cookie。这里值得注意的是,设定的日期和时间只与客户端相关,而不是服务端。

Max-Age

Max-Age 用于设置在 Cookie 失效之前需要经过的秒数。比如:

1
2
Set-Cookie: id=a3fWa; Max-Age=604800;
复制代码

Max-Age 可以为正数、负数、甚至是 0。

如果 max-Age 属性为正数时,浏览器会将其持久化,即写到对应的 Cookie 文件中。

当 max-Age 属性为负数,则表示该 Cookie 只是一个会话性 Cookie。

当 max-Age 为 0 时,则会立即删除这个 Cookie。

假如 Expires 和 Max-Age 都存在,Max-Age 优先级更高。

Domain

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

像淘宝首页设置的 Domain 就是 .taobao.com,这样无论是 a.taobao.com 还是 b.taobao.com 都可以使用 Cookie。

在这里注意的是,不能跨域设置 Cookie,比如阿里域名下的页面把 Domain 设置成百度是无效的:

1
2
Set-Cookie: qwerty=219ffwef9w0f; Domain=baidu.com; Path=/; Expires=Wed, 30 Aug 2020 00:00:00 GMT
复制代码

Path

Path 指定了一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。比如设置 Path=/docs/docs/Web/ 下的资源会带 Cookie 首部,/test 则不会携带 Cookie 首部。

Domain 和 Path 标识共同定义了 Cookie 的作用域:即 Cookie 应该发送给哪些 URL。

Secure属性

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

HTTPOnly

设置 HTTPOnly 属性可以防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击。

SameSite属性

SameSite 是最近非常值得一提的内容,因为 2 月份发布的 Chrome80 版本中默认屏蔽了第三方的 Cookie。

作用

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

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 的协议/主机名/端口一致。例如,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.comwww.baidu.com 是跨站,www.a.taobao.comwww.b.taobao.com 是同站,a.github.io 和 b.github.io 是跨站(注意是跨站)。

改变

接下来看下从 None 改成 Lax 到底影响了哪些地方的 Cookies 的发送?直接来一个图表:

img

从上图可以看出,对大部分 web 应用而言,Post 表单,iframe,AJAX,Image 这四种情况从以前的跨站会发送三方 Cookie,变成了不发送。

Post表单:应该的,学 CSRF 总会举表单的例子。

iframe:iframe 嵌入的 web 应用有很多是跨站的,都会受到影响。

AJAX:可能会影响部分前端取值的行为和结果。

Image:图片一般放 CDN,大部分情况不需要 Cookie,故影响有限。但如果引用了需要鉴权的图片,可能会受到影响。

除了这些还有 script 的方式,这种方式也不会发送 Cookie,像淘宝的大部分请求都是 jsonp,如果涉及到跨站也有可能会被影响。

文章目录
  1. 1. HTTP
  2. 2. Cookie
    1. 2.1. Cookie的设置
    2. 2.2. Cookie属性
      1. 2.2.1. Name/Value
      2. 2.2.2. Expires
      3. 2.2.3. Max-Age
      4. 2.2.4. Domain
      5. 2.2.5. Path
      6. 2.2.6. Secure属性
      7. 2.2.7. HTTPOnly
    3. 2.3. SameSite属性
      1. 2.3.0.1. 作用
      2. 2.3.0.2. 属性值
      3. 2.3.0.3. 跨域和跨站
      4. 2.3.0.4. 改变