为什么要有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的携带,其值有三个none、strict、lax。
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> | 不发送 |
| AJAX | axios.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