cooke知识整理

23 阅读5分钟

概念

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)的保护。

第三方cookie

A网站已有cookie,你点击了一个恶意网站B,B诱骗你点击一个表单,该表单向A网站发起请求。这种第三方网站引导发出的cookie,就称为第三方cookie。它除了用于CSRF攻击,还可以用于用户追踪。

Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。

它采用三个可能的值:StrictLax 和 None

  • Strict

Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

  • Lax(默认)

Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

  • None

在同站请求和跨站请求下继续发送 cookie,但仅在安全的上下文中(即,如果 SameSite=None,且还必须设置 Secure 属性)。

请求类型示例NoneLaxStrict
链接<a href="..."></a>发送 Cookie发送 Cookie不发送
预加载<link rel="prerender" href="..."/>发送 Cookie发送 Cookie不发送
GET 表单<form method="GET" action="...">发送 Cookie发送 Cookie不发送
POST 表单<form method="POST" action="...">发送 Cookie不发送不发送
iframe<iframe src="..."></iframe>发送 Cookie不发送不发送
AJAX$.get("...")发送 Cookie不发送不发送
Image<img src="...">发送 Cookie不发送不发送

设置了StrictLax以后,基本就杜绝了 CSRF 攻击。

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。

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

const day = 24 * 60 * 60 * 1000;

cookieStore.set({
  name: "cookie1",
  value: "cookie1-value",
  expires: Date.now() + day,
  domain: "example.com",
});

获取cookie

const cookie = await cookieStore.get("cookie1");

if (cookie) {
  console.log(cookie);
} else {
  console.log("Cookie 未找到");
}

CookieStore 接口的 getAll()  方法返回与传递给它的 name 或 options 匹配的所有 cookie 列表。不传递任何参数将返回当前上下文的所有 cookie。

const cookies = await cookieStore.getAll();

if (cookies.length > 0) {
  console.log(cookies);
} else {
  console.log("Cookie 未找到");
}

删除cookie

const result = await cookieStore.delete("cookie1");

console.log(result);

监听cookie变化

cookieStore.addEventListener("change", (event) => {
  console.log("cookie 变更事件");
});
cookieStore.onchange = (event) => {
  console.log("cookie 变更事件");
};

安全

  • 使用 HttpOnly 属性可防止通过 JavaScript 访问 cookie 值。
  • 用于敏感信息(例如指示身份验证)的 Cookie 的生存期应较短,并且 SameSite 属性设置为 Strict 或 Lax。(请参见上方的 SameSite 属性。)在支持 SameSite 的浏览器中,这样做的作用是确保不与跨站点请求一起发送身份验证 cookie。因此,这种请求实际上不会向应用服务器进行身份验证。

参考

https://develo

per.mozilla.org/zh-CN/docs/Web/HTTP/Guides/Cookies juejin.cn/post/696882… www.ruanyifeng.com/blog/2019/0…