查漏补缺--Cookie

656 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情

  • 写这篇是因为我在调试的时候看到了SameSite的问题,所以决定把Cookie相关的捋清楚,很喜欢这种被问题带动学习的方式哈哈

一、基本了解

作用:

用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能

生命周期

  • 会话期 Cookie 是最简单的 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。会话期 Cookie 不需要指定过期时间(Expires)或者有效期(Max-Age)。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样,这会导致 Cookie 的生命周期无限期延长。
  • 持久性 Cookie 的生命周期取决于过期时间(Expires)或有效期(Max-Age)指定的一段时间。

属性

  • 我们直接从掘金首页随便找一个请求看看,按照它的顺序依次来了解 image.png
  • Name: Cookie的名称
  • Value: Cookie的值
  • Domain:
    • 可以指定可以访问该Cookie的域名。这里设置为“.juejin.cn”,则所有以“juejin.cn”结尾的域名都可以访问该Cookie,例如".mouche.juejin.cn"
    • 如果没有指定,则默认为当前文档访问地址中的主机部分(不包括子域名)
  • Path
    • 指定一个URL路径,这个路径必须出现在请求的资源的路径汇总才可以发送Cookie
    • 如果设置为‘/’,即表示本域名下的所有路径都可以访问该Cookie
    • 如果设置为“/mouche/”,那么
      • /mouche/name’, ‘/mouche/login’都满足匹配条件
      • /’, ‘/name/mouche’, ‘/mouch’ 则不满足要求
  • Expires/Max-Age
    • Expires: Cookie的最长有效时间,格式为GMT;截止时间与客户端相关,而非服务器的时间

    但是很多Web浏览器支持会话恢复,在还原的过程中,Cookie也会恢复

    • Max-Age: 在Cookie失效之前需要经过的秒数,秒数为 0 或者 -1 的话会让Cookie直接过期

    Max-Age优先级高于Expires

    • 如果没有Expires或者Max-Age,那么则是会话期Cookie,如果客户端被关闭时,那么就会将该Cookie移除;
  • Size: 指的Cookie大小
  • HttpOnly: 用于阻止JavaScript通过Document.cookie访问Cookie,在一定程序上防范了跨站脚本攻击XSS
    • 我们可以试一下(有点多,一共能打印出八条) image.png
    • 然后我们可以去寻找一下Cookie,会发现这八条确实就是HttpOnly值false的Cookie

image.pngimage.png

  • Secure:
    • 非安全站点(http:)不能在Cookie中设置Secure属性,只有在请求使用https协议的时候才会被发送到服务器,以防止中间人攻击(不过好像也是不能够完全阻止)
    • 携带这个属性的Cookie,如果没有设置HttpOnly的情况下仍然能够通过JavaScript访问,例如我们上面打印出来的名称为__jj_ext的Cookie,secure值为true,但是照样能被打印 image.png
  • Priority:
    • 定义了三种优先级,Low/Medium(默认)/High,当cookie数量超出限制的时候,低优先级的Cookie会被优先清除掉
    • 不过这个不是每个浏览器都有,我试了一下火狐无 image.png

二、SameSite

  • 查了一下Chrome推出的51版本就设置了samesite属性了

同站

  • 同站相对于同源来说更宽松一些
  • 只要两个 URLeTLD+1 相同即可,不需要考虑协议和端口。其中,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1 则表示,有效顶级域名+二级域名,例如taobao.com
  • so,如果跨站了那么一般都是不同源的

比如说,.org是有效的顶级域名,那么https://blog.imnerd.orghttps://www.imnerd.org则算同站,但是不同源

属性

  • Strict: 浏览器仅对同一站点的请求发送Cookie,如果请求来自与设置Cookie的站点不同的站点,则Cookie不会被发送;完全禁止第三方 Cookie; 限制得这么严格也就说明它的用户体验也会随之下降

打个比方,我本来已经登录了GitHub,然后我现在每次从掘金点击打开GitHub网站,因为跳转链接不会携带cookie,我们的信息没有办法得到认证,故又得重新登录

  • Lax:相对于Strict则会宽松一点, 允许Get请求

比如我在A站点点击了B站点,B站点使用了samesite=Lax,如果使用Get请求,那么就可以正常登录B站点,相对地,如果使用POST请求将被阻止

  • None:不限制,但是你如果设置为None的话就必须设置Securetrue,也就是说必须是使用https协议 image.png

Chorme80以前默认为none,现在都默认为Lax image.png

  • 目的: 让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)

  • 最后是查了一下兼容性,目前主流浏览器都是支持的

    image.png