记录下浏览器的cookie

323 阅读5分钟
  • 跨域携带cookie

    • cookie 的大小一般被浏览器限制为 4kb

    • Domain 表示 Cookie 的作用域,如果后端未指定 Domain,那么默认情况下,域的值就与 document.domain或者 location.hostname相等。默认是不包含子域的,但是后端设置 Domain 后就可以在子域之间共享

      • 如果服务端设置了 Domain,无论前面是否加点,最终生效后一定会加点

        // node服务设置cookie domain=test.com 
        // 浏览器application内的cookie显示的domain也还是 .test.com
        res.setHeader('Set-cookie', ['name=ming;domain=test.com']);
        
      • 如果服务端设置的 Cookie 不包含在当前的 document.domain 中,那么会被浏览器拒绝。eg:不能在 test.com设置cookie的domain为 a.test.com ,但是反过来是可以的。保证了安全性

      • Cookie 的作用域与端口号无关

      • Cookie 的作用域与协议无关

    • Path 这个属性可以指定可以共享 Cookie 的子目录,默认就是 /根目录,因为设置为根目录,所有子目录可以共享,如果指定子目录的话,其上级目录则无法访问该 Cookie

      // 给name cookie设置path为 /set
      // 只能在目录 /set 以及子目录 /set/xx/xx 中共享
      // 如果访问其他目录,例如根目录 / 和 /get 目录中是看不到的
      res.setHeader('Set-Cookie', ['name=ming;domain=test.com;path=/set;'])
      
    • Expires/Max-Age 用于设置 Cookie 的有效期,如果没有设置,默认是 Session,即会话期间有效。所谓的「会话期间」是指当客户端被关闭时,cookie 就会被移除。但是这个不是严格意义上的浏览器关了,Cookie 就没了。因为很多Web浏览器支持会话恢复功能,用户重新打开浏览器的时候 cookie 也会恢复。

      // 设置Expires 指定具体的过期时间
      // 设置时间使用toUTCString 或者 toGMTString(主要是用来满足旧代码兼容性的,已经从 Web 标准中删除)
      // 如果使用 toISOString 会被认为是会话级别的Cookie
      res.setHeader('Set-Cookie', [
        `name=ming; expires=${new Date(Date.now() + 10 * 1000).toGMTString()}`,
      ])
      
      // 设置Max-age 单位为秒
      res.setHeader('Set-Cookie', ['name=keliq; max-age=10;'])
      
      // 如果 Max-Age 和 Expires 同时存在,那么 Max-Age 优先级更高。
      
    • HttpOnly 设置了 HttpOnly 属性的 Cookie 不能被 JavaScript 获取到,这是非常安全的

      // 这个时候通过 document.cookie 是获取不到 name 值的
      res.setHeader('Set-Cookie', 
      [
        `name=ming; 
      	 expires=${new Date(Date.now() + 10 * 1000).toUTCString()};
      	 httpOnly=true;`
      ])
      
    • Secure 这是 Cookie 的安全属性,只有当使用 SSL 和 HTTPS 协议的时候才会被发送。如果服务器是 HTTP 的,但是设置了 Secure,那么客户端是收不到这个 Cookie 的。严格意义上来讲,是浏览器拒绝接受这个 Cookie,实际上 Set-Cookie 请求头里面是有这些数据的。

      res.setHeader('Set-Cookie', [
        `name=ming;Secure`
      ])
      
    • SameSite 该属性用于限制第三方 Cookie 的发送场景(可以防御CSRF攻击),可以取值:

      • Strict:完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。

      • Lax:默认值。除了下面三种情况外,不发送第三方 Cookie

        • 链接:<a href="..."></a>
        • 预加载请求:<link rel="prerender" href="..."/>
        • GET 表单:<form method="GET" action="...">
      • None:跨站都发送 Cookie(设为none的时候必须开启 Secure 属性,否则cookie会设置失败)

      在 Chrome 80版本后 SameSite的默认值被设定为 SameSite=Lax

    • SameParty 这个属性就是为了配合 First-Party Sets使用的。所有开启了 First-Party Sets域名下需要共享的 Cookie都需要增加 SameParty属性。(First-Party Sets  可以定义跨站点上下文仍然是 first-party的情况。 Cookie可以包含在第一方集合中,也可以排除在第三方上下文中。First-Party Sets提出了一种明确定义在同一主体下拥有和运营的多个站点关系的方法。比如 .tmall.comtaobao.com都可以被定义为同一主体运营 。)

      // 假设test.com 和 test.top 设置了First-Party Sets
      res.setHeader('Set-Cookie', [
        `name=ming;SameSite=Strict;SameParty;Secure`
      ])
      // 如果在test.com 设置了cookie SameParty,那么在test.top也可以携带name,
      // 而其他网站发送请求时cookie不会被携带
      
      • SameParty 被广泛支持之前,可以把它和 SameSite 属性一起定义来确保 Cookie 的行为降级,另外还有一些额外的要求:

        • SameParty Cookie 必须包含 Secure
        • SameParty Cookie 不得包含 SameSite=Strict
    • Priority 优先级 (暂时只有谷歌支持)Priority 可取的值为:

      • Low

      • Medium(默认为该值)

      • High

    RFC 6265 - HTTP State Management Mechanism 提案要求客户端需要为每一种优先级的 Cookie 设定一个至少保留值。在移除 Cookie 的时候,执行如下策略(每一条都遵循 LRA 的策略剔除 Cookie):

    1. 从过期的 Cookie 中
    2. 从 Cookie 数超出预定义数量的域名中删除优先级为 Low 的 Cookie,并保留其最小保留值
    3. 从 Cookie 数超出预定义数量的域名中删除优先级为 Low 和 Medium 的 Cookie,同时需要保留优先级为 Low 以及优先级为 Medium 的 Cookie 至少保留量之和的 Low 与 Medium 的 Cookie
    4. 从 Cookie 超出预定义数量的域名中
    5. 从所有 Cookie 中

    谷歌似乎对 Cookie 的优先级问题十分上心,在 2017 年又有一个提案draft-ietf-httpbis-rfc6265bis-02 - Cookies: HTTP State Management Mechanism,其 Cookie 移除策略如下:

    1. 从过期的 Cookie 中
    2. 从 Cookie 数超出预定义数量的域名中删除未设置 secure-only 标志的 Cookie
    3. 从 Cookie 超出预定义数量的域名中
    4. 从所有 Cookie 中

    目前 Chrome 对 Cookie 的实现是上面两种的混合,其优先级从低到高为:

    1. 优先级为 Low 的非 secure Cookie
    2. 优先级为 Low 的 secure Cookie
    3. 优先级为 Medium 的非 secure Cookie
    4. 优先级为 Medium 的 secure Cookie
    5. 优先级为 High 的非 secure Cookie
    6. 优先级为 High 的 secure Cookie

    Chrome 会按照从低到高的顺序最多进行 6 轮移除过程,当移除非 secure 的 Cookie 后已经到达对应优先级的至少保留值时,不会再去剔除对应优先级的 secure Cookie。

  • partition key