cookie

64 阅读3分钟

cookie?

Cookies 是浏览器本地保存数据的一种方案,且会在每次请求中带上该字段。

cookie 最常见的用法是作为用户登录凭证,赋予原本没有状态的 HTTP 协议以一种状态,让识别一个请求是哪一个用户发出成为可能。

怎么设置cookie?

HTTP 响应报文通过 Set-Cookie 头字段给浏览器给当前网站设置 cookie:

HTTP/1.1 200 OK
Set-Cookie: lang=en-US; Path=/
Set-Cookie: token=abcd; Max-Age=6000; Path=/; Expires=Thu, 28 Apr 2022 16:31:36 GMT; HttpOnly

当然也可以在浏览器用 JS 脚本通过 document.cookie 或 CookieStore 来设置 cookie。

浏览器拿到 cookie 后,会将它们保存下来,在下一次请求时将这些 cookie 全放到 Cookie 请求头中,并用分号分隔:

GET / HTTP/1.1
Cookie: lang=en-US; token=abcd

需要特别注意的是,Cookie 的作用域是和 domain(域名或 ip)绑定的,端口无关。 不同端口会带上cookie

cookie属性

1. cookieName=cookieValue 设置cookie名字和值-必填项

Set-Cookie: token=abcd

2. HttpOnly

Set-Cookie: token=abcd; HttpOnly

设置后,只能通过 HTTP 响应报文的 Set-Cookie 来新增或更新 cookie ,客户端无法通过脚本的方式来读写 cookie。

对于敏感信息比如用户凭证,请一定要加上 HttpOnly。如果攻击者成功地实施了 XSS 攻击,会因为无法读取 cookie 而拿不到敏感信息。

3. Expires - cookie 的过期时间点,使用了 GMT 时间格式的字符串。

Set-Cookie: token=abcd; Expires=Fri, 29 Apr 2022 05:29:01 GMT

4. Max-Age - cookie 的有效时间长度,单位为秒。

通过设置小于等于 0 的数字,可以让一个 cookie 失效。

如果 Max-Age 和 Expires 同时存在,以 Max-Age 为准。

如果 Expires 和 Max-Age 都没设置,cookie 的有效期就会设置为 session, 一种临时会话状态,会在浏览器关闭时销毁。不过也不总是这样,这个得看浏览器实现,总之不会保存太久就是了。

Set-Cookie: token=abcd; Max-Age=6000

5. SameSite - cookie 在跨域时是否应该被发送。

Set-Cookie: token=abcd; SameSite=Strict

cookie 在跨域时是否应该被发送。

Strict:跨域请求严禁携带本站 cookie。

Lax:默认值。可通过顶级导航的方式并使用 GET 请求发时可以携带(目前我没有通过 demo 实现该效果,或者我们可以将其无限接近于 Strict)。在 Chrome 80 版本之后,Cookie 的 SameSite 由原来的 None 改为了 Lax。

None:会携带 cookie。但前提是 Secure 设置为 true,即只能在 HTTPS 协议下使用(之前的标准没有这个要求)。

6. Path - 设置 cookie 的路径作用域。

Set-Cookie: lang=en-US; Path=/user

怎么理解?

我们以上面示例为例,浏览器会将名为 lang 的 cookie 保存到当前域名下。但之后请求时,会判断路径是否匹配 /user,来决定是否带上 cookie。

/ :不会带上名为 lang 的 cookie

/user:会带上

/user/1:会带上

/user2:不会带上

不过实际开发时我们都是直接使用 Path=/,简单粗暴覆盖所有路径,没有必要分路径,让事情变得复杂。上面的知识点,大家简单了解就好。

7. Domain

Set-Cookie: lang=en-US; Domain=.a.com

设置 cookie 的 domain 作用域。

在不提供该属性的情况下,会使用请求时的 domian,比如 www.a.com/api/v1/book… 不设置 Domain 时,拿到的 cookie 的 Domain 属性会被设置为 www.a.com

通常我们会省略掉 Domain 属性。

但在希望多个子域名共享 cookie 的场景下,比如 sub1.a.com 和 sub2.a.com(或者再加上父域名 a.com),就需要显式将其设置为 .a.com。开头的小圆点可写可不写,都一样。

8. Secure

Set-Cookie: token=en-US; Secure

该属性没有值,属性本身存在就代表设置为安全模式

即请求必须为安全连接(HTTPS),cookie 才会被保存下来。HTTP 协议下,cookie 无效。