cookie详解/same-site有什么用?

166 阅读3分钟

为什么要有cookie?

Cookie是由W3C组织提出,最早由NetScape社区发展的一种机制。

Cookie是存储于访问者的计算机中的变量。每当同一台计算机通过浏览器请求某个页面时,就会发送这个cookie。

Cookie的作用就是用于解决"如何记录客户端的用户信息"

  • 当用户访问web页面时,他的名字可以记录在Cookie中。

  • 在用户下一次访问该页面时,可以在Cookie中读取用户访问记录。

大小约4kb

cookie属性

name: cookie名,不可更改

value:cookie值

maxAge:Cookie失效的时间,单位秒。如果为整数,则该Cookie在maxAge秒后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为-1。

secure:该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。

domain: 可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。

httpOnly:禁止js用document.cookie拿到cookie。

sameSite:制约第三方cookie的携带,其值有三个nonestrictlax

priority: 优先级,cookie数量超出限制时,优先级低的会被清除


domain

一般在实现单点登录的时候会经常用到这个属性,通过在父级域设置Cookie,然后在各个子级域拿到存在父级域中的Cookie值。

在'.a.com'下设置cookie,'.b.a.com'也可以拿到。

不设置默认为当前域名,子域名也拿不到。

只有请求域名是domain的值时才有效

  • 网页www.a.com/index.html的前端页面,去请求接口www.b.com/api

  • 网页www.b.com/index.html的前端页面,去请求接口www.a.com/api

  • 网页www.a.com/index.html的前端页面,去请求接口www.a.com/api

只有后两个会携带cookie

path

类似domain

在'/a'下设置,'/a/b'也可以拿到。

所有子路径都可以访问。

sameSite

为什么需要?

对三方cookie的限制一是为了浏览器安全,但在国外推动的更重要原因是个人的隐私安全。

可选值:

  • strict代表完全禁止三方cookie,这是最严格防护,可以避免被CSRF攻击,但缺点也很明显,像天猫、淘宝这种同属一个主体运营的网站不得不重复登录;

  • none代表完全不做限制,即之前「不认来源,只看目的」的cookie取用原则;

  • Lax则是折中,在某些情况下会限制三方cookie的携带,某些情况又放行,这也是浏览器的默认值(包括safari)。

同上文,在设置了 sameSite = strict 时,只有第三种会携带。

  • 网页www.a.com/index.html的前端页面,去请求接口www.b.com/api

  • 网页www.b.com/index.html的前端页面,去请求接口www.a.com/api

  • 网页www.a.com/index.html的前端页面,去请求接口www.a.com/api

sameSite = lax 具体规则如下

类型例子是否发送
a链接<a href="..."></a>发送
预加载<link rel="prerender" href="..."/>发送
GET 表单<form method="GET" action="...">发送
POST 表单<form method="POST" action="...">不发送
iframe<iframe src="..."></iframe>不发送
AJAXaxios.post不发送
图片<img src="..."></a>不发送

解决方案:

sameParty

same-party可以把.taobao.com.tmall.com.alimama.com三个站合起来,它们设置的cookie在这个集合内部不会被当作第三方cookie对待。需要在服务器端进行配置

需要注意的是,使用same-party属性时,必须要同时使用https(secure属性),并且same-site不能是strict。

axios踩坑

const res = await api.get('http://localhost:3000/');
return res['set-cookie']; // undefined,axios的问题
    
document.cookie // 可以拿到cookie

参考文章

juejin.cn/post/708720…

juejin.cn/post/696363…