持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
- 写这篇是因为我在调试的时候看到了SameSite的问题,所以决定把Cookie相关的捋清楚,很喜欢这种被问题带动学习的方式哈哈
一、基本了解
作用:
用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能
生命周期
- 会话期 Cookie 是最简单的 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。会话期 Cookie 不需要指定过期时间(
Expires)或者有效期(Max-Age)。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样,这会导致 Cookie 的生命周期无限期延长。 - 持久性 Cookie 的生命周期取决于过期时间(
Expires)或有效期(Max-Age)指定的一段时间。
属性
- 我们直接从掘金首页随便找一个请求看看,按照它的顺序依次来了解
- Name: Cookie的名称
- Value: Cookie的值
- Domain:
- 可以指定可以访问该Cookie的域名。这里设置为“
.juejin.cn”,则所有以“juejin.cn”结尾的域名都可以访问该Cookie,例如".mouche.juejin.cn" - 如果没有指定,则默认为当前文档访问地址中的主机部分(不包括子域名)
- 可以指定可以访问该Cookie的域名。这里设置为“
- 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- 我们可以试一下(有点多,一共能打印出八条)
- 然后我们可以去寻找一下Cookie,会发现这八条确实就是
HttpOnly值为false的Cookie
- 我们可以试一下(有点多,一共能打印出八条)
- Secure:
- 非安全站点(
http:)不能在Cookie中设置Secure属性,只有在请求使用https协议的时候才会被发送到服务器,以防止中间人攻击(不过好像也是不能够完全阻止) - 携带这个属性的Cookie,如果没有设置
HttpOnly的情况下仍然能够通过JavaScript访问,例如我们上面打印出来的名称为__jj_ext的Cookie,secure值为true,但是照样能被打印
- 非安全站点(
- Priority:
- 定义了三种优先级,
Low/Medium(默认)/High,当cookie数量超出限制的时候,低优先级的Cookie会被优先清除掉 - 不过这个不是每个浏览器都有,我试了一下火狐无
- 定义了三种优先级,
二、SameSite
- 查了一下
Chrome推出的51版本就设置了samesite属性了
同站
- 同站相对于同源来说更宽松一些
- 只要两个
URL的eTLD+1相同即可,不需要考虑协议和端口。其中,eTLD表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1则表示,有效顶级域名+二级域名,例如taobao.com等 - so,如果跨站了那么一般都是不同源的
比如说,.org是有效的顶级域名,那么
https://blog.imnerd.org和https://www.imnerd.org则算同站,但是不同源
属性
- Strict: 浏览器仅对同一站点的请求发送Cookie,如果请求来自与设置Cookie的站点不同的站点,则Cookie不会被发送;完全禁止第三方 Cookie; 限制得这么严格也就说明它的用户体验也会随之下降
打个比方,我本来已经登录了GitHub,然后我现在每次从掘金点击打开GitHub网站,因为跳转链接不会携带cookie,我们的信息没有办法得到认证,故又得重新登录
- Lax:相对于Strict则会宽松一点, 允许Get请求
比如我在A站点点击了B站点,B站点使用了
samesite=Lax,如果使用Get请求,那么就可以正常登录B站点,相对地,如果使用POST请求将被阻止
- None:不限制,但是你如果设置为
None的话就必须设置Secure为true,也就是说必须是使用https协议
Chorme80以前默认为none,现在都默认为Lax
-
目的: 让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)
-
最后是查了一下兼容性,目前主流浏览器都是支持的