概念
HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。
浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器------如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。
作用
-
会话状态管理
- 如用户登录状态、购物车、游戏分数或其他需要记录的信息
-
个性化设置
- 如用户自定义设置、主题和其他设置
-
浏览器行为跟踪
- 如跟踪分析用户行为等
生命周期
- 会话期 Cookie 会在当前的会话结束之后删除。浏览器定义了"当前会话"结束的时间,一些浏览器重启时会使用会话恢复。这可能导致会话 cookie 无限延长。
- 持久性 Cookie 在过期时间(
Expires
)指定的日期或有效期(Max-Age
)指定的一段时间后被删除。
配置属性
name
value
Domain
Domain
指定了哪些主机可以接受 Cookie。
如果不指定,该属性默认为同一 host 设置 cookie,不包含子域名。
如果指定了 Domain
,则一般包含子域名。
Path
Path
属性指定了一个 URL 路径,该 URL 路径必须存在于请求的 URL 中,以便发送 Cookie
标头。以字符 %x2F
("/") 作为路径分隔符,并且子路径也会被匹配。
Expires、Max-Age
Expires 是一个绝对时间,如果没有设置这个属性或者设置为 null,则表示这是一个Session Cookie。需要注意的是,浏览器是根据本地时间与 Expires 对比判断是否过期,而本地时间是可能变动的,所以无法保证 Cookie 一定会在服务器指定的时间过期。
Max-Age 是一个相对时间,是在 Cookie 失效之前需要经过的秒数。秒数为 0 或 -1 将会使 Cookie 直接过期。
如果同时指定了 Expires 和 Max-Age ,那么 Max-Age 的值将优先生效。
SameSite
SameSite
属性允许服务器指定是否/何时通过跨站点请求发送(其中站点由注册的域和方案 定义:http 或 https)。这提供了一些针对跨站点请求伪造攻击(CSRF)的保护。它采用三个可能的值:Strict
、Lax
和 None
。
- Strict
仅发送到它来源的站点
- Lax(默认)
与 Strict 相似,只是在用户导航到 cookie 的源站点时发送 cookie。
- None
在同站请求和跨站请求下继续发送 cookie,但仅在安全的上下文中 (即,如果 SameSite=None
,且还必须设置 Secure
属性)。
HttpOnly
JavaScript Document.cookie
API 无法访问带有 HttpOnly
属性的 cookie
此预防措施有助于缓解跨站点脚本(XSS)攻击。
Secure
标记为 Secure
的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端。
这意味着中间人攻击者无法轻松访问它
Cookie 前缀
cookie 的机制使得服务器无法确认 cookie 是在安全来源上设置的,甚至无法确定 cookie 最初是在哪里设置的。
子域上的易受攻击的应用程序可以使用 Domain
属性设置 cookie,从而可以访问所有其他子域上的该 cookie。会话劫持 攻击中可能会滥用此机制。有关主要缓解方法,请参阅会话劫持(session fixation)。
如果 cookie 名称具有此前缀,则仅当它也用 Secure
属性标记、从安全来源发送、不包括 Domain
属性,并将 Path
属性设置为 /
时,它才在 Set-Cookie
标头中接受。这样,这些 cookie 可以被视为"domain-locked"。
如果 cookie 名称具有此前缀,则仅当它也用 Secure
属性标记,是从安全来源发送的,它才在 Set-Cookie
标头中接受。该前缀限制要弱于 __Host-
前缀。
操作cookie API
document.cookie
通过 Document.cookie
属性可创建新的 Cookie。如果未设置 HttpOnly
标记,你也可以从 JavaScript 访问现有的 Cookie。
ini
document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);
// logs "yummy_cookie=choco; tasty_cookie=strawberry"
通过 JavaScript 创建的 Cookie 不能包含 HttpOnly
标志。
CookieStore
Cookie Store API 的 CookieStore
接口提供了在页面或 Service Worker 中异步设置和获取 cookies 的方法
CookieStore
通过 Window
或 ServiceWorkerGlobalScope
上下文的全局范围内的属性进行访问。因此,不存在构造函数。
设置cookie
php
const day = 24 * 60 * 60 * 1000;
cookieStore.set({
name: "cookie1",
value: "cookie1-value",
expires: Date.now() + day,
domain: "example.com",
});
获取cookie
javascript
const cookie = await cookieStore.get("cookie1");
if (cookie) {
console.log(cookie);
} else {
console.log("Cookie 未找到");
}
CookieStore
接口的 getAll()
方法返回与传递给它的 name
或 options
匹配的所有 cookie 列表。不传递任何参数将返回当前上下文的所有 cookie。
javascript
const cookies = await cookieStore.getAll();
if (cookies.length > 0) {
console.log(cookies);
} else {
console.log("Cookie 未找到");
}
删除cookie
ini
const result = await cookieStore.delete("cookie1");
console.log(result);
监听cookie变化
javascript
cookieStore.addEventListener("change", (event) => {
console.log("cookie 变更事件");
});
ini
cookieStore.onchange = (event) => {
console.log("cookie 变更事件");
};
安全
- 使用
HttpOnly
属性可防止通过 JavaScript 访问 cookie 值。 - 用于敏感信息(例如指示身份验证)的 Cookie 的生存期应较短,并且
SameSite
属性设置为Strict
或Lax
。(请参见上方的 SameSite 属性。)在支持 SameSite 的浏览器中,这样做的作用是确保不与跨站点请求一起发送身份验证 cookie。因此,这种请求实际上不会向应用服务器进行身份验证。
参考
developer.mozilla.org/zh-CN/docs/... juejin.cn/post/696882...