Skip to content

Commit 4f78aa4

Browse files
committed
docs(bom): edit Cookie
1 parent 304fd07 commit 4f78aa4

File tree

1 file changed

+106
-14
lines changed

1 file changed

+106
-14
lines changed

docs/bom/cookie.md

Lines changed: 106 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,36 @@
22

33
## 概述
44

5-
Cookie 是服务器保存在浏览器的一小段文本信息,每个 Cookie 的大小一般不能超过4KB。浏览器每次向服务器发出请求,就会自动附上这段信息。
5+
Cookie 是服务器保存在浏览器的一小段文本信息,一般大小不能超过4KB。浏览器每次向服务器发出请求,就会自动附上这段信息。
66

7-
Cookie 主要用来分辨两个请求是否来自同一个浏览器,以及用来保存一些状态信息。它的常用场合有以下一些
7+
Cookie 主要保存状态信息,以下是一些主要用途
88

99
- 对话(session)管理:保存登录、购物车等需要记录的信息。
10-
- 个性化:保存用户的偏好,比如网页的字体大小、背景色等等。
11-
- 追踪:记录和分析用户行为。
10+
- 个性化信息:保存用户的偏好,比如网页的字体大小、背景色等等。
11+
- 追踪用户:记录和分析用户行为。
1212

13-
有些开发者使用 Cookie 作为客户端储存。这样做虽然可行,但是并不推荐,因为 Cookie 的设计目标并不是这个,它的容量很小(4KB),缺乏数据操作接口,而且会影响性能。客户端储存应该使用 Web storage API 和 IndexedDB。
13+
Cookie 不是一种理想的客户端储存机制。它的容量很小(4KB),缺乏数据操作接口,而且会影响性能。客户端储存应该使用 Web storage API 和 IndexedDB。只有那些每次请求都需要让服务器知道的信息,才应该放在 Cookie 里面
1414

15-
Cookie 包含以下几方面的信息
15+
每个 Cookie 都有以下几方面的元数据
1616

1717
- Cookie 的名字
1818
- Cookie 的值(真正的数据写在这里面)
19-
- 到期时间
20-
- 所属域名(默认是当前域名
21-
- 生效的路径(默认是当前网址
19+
- 到期时间(超过这个时间会失效)
20+
- 所属域名(默认为当前域名
21+
- 生效的路径(默认为当前网址
2222

23-
举例来说,用户访问网址`www.example.com`,服务器在浏览器写入一个 Cookie。这个 Cookie 就会包含`www.example.com`这个域名,以及根路径`/`这意味着,这个 Cookie 对该域名的根路径和它的所有子路径都有效。如果路径设为`/forums`,那么这个 Cookie 只有在访问`www.example.com/forums`及其子路径时才有效。以后,浏览器一旦访问这个路径,浏览器就会附上这段 Cookie 发送给服务器
23+
举例来说,用户访问网址`www.example.com`,服务器在浏览器写入一个 Cookie。这个 Cookie 的所属域名为`www.example.com`,生效路径为根路径`/`如果 Cookie 的生效路径设为`/forums`,那么这个 Cookie 只有在访问`www.example.com/forums`及其子路径时才有效。以后,浏览器访问某个路径之前,就会找出对该域名和路径有效,并且还没有到期的 Cookie,一起发送给服务器
2424

25-
浏览器可以设置不接受 Cookie,也可以设置不向服务器发送 Cookie。`window.navigator.cookieEnabled`属性返回一个布尔值,表示浏览器是否打开 Cookie 功能。
25+
用户可以设置浏览器不接受 Cookie,也可以设置不向服务器发送 Cookie。`window.navigator.cookieEnabled`属性返回一个布尔值,表示浏览器是否打开 Cookie 功能。
2626

2727
```javascript
28-
// 浏览器是否打开 Cookie 功能
2928
window.navigator.cookieEnabled // true
3029
```
3130

3231
`document.cookie`属性返回当前网页的 Cookie。
3332

3433
```javascript
35-
// 当前网页的 Cookie
36-
document.cookie
34+
document.cookie // "id=foo;key=bar"
3735
```
3836

3937
不同浏览器对 Cookie 数量和大小的限制,是不一样的。一般来说,单个域名设置的 Cookie 不应超过30个,每个 Cookie 的大小不能超过4KB。超过限制以后,Cookie 将被忽略,不会被设置。
@@ -181,6 +179,95 @@ Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
181179

182180
上面是跨站点载入的一个恶意脚本的代码,能够将当前网页的 Cookie 发往第三方服务器。如果设置了一个 Cookie 的`HttpOnly`属性,上面代码就不会读到该 Cookie。
183181

182+
### SameSite
183+
184+
Chrome 51 开始,浏览器的 Cookie 新增加了一个`SameSite`属性,用来防止 CSRF 攻击和用户追踪。
185+
186+
Cookie 往往用来存储用户的身份信息,恶意网站可以设法伪造带有正确 Cookie 的 HTTP 请求,这就是 CSRF 攻击。举例来说,用户登陆了银行网站`your-bank.com`,银行服务器发来了一个 Cookie。
187+
188+
```http
189+
Set-Cookie:id=a3fWa;
190+
```
191+
192+
用户后来又访问了恶意网站`malicious.com`,上面有一个表单。
193+
194+
```html
195+
<form action="your-bank.com/transfer" method="POST">
196+
...
197+
</form>
198+
```
199+
200+
用户一旦被诱骗发送这个表单,银行网站就会收到带有正确 Cookie 的请求。为了防止这种攻击,表单一般都带有一个随机 token,告诉服务器这是真实请求。
201+
202+
```html
203+
<form action="your-bank.com/transfer" method="POST">
204+
<input type="hidden" name="token" value="dad3weg34">
205+
...
206+
</form>
207+
```
208+
209+
这种第三方网站引导发出的 Cookie,就称为第三方 Cookie。它除了用于 CSRF 攻击,还可以用于用户追踪。比如,Facebook 在第三方网站插入一张看不见的图片。
210+
211+
```html
212+
<img src="facebook.com" style="visibility:hidden;">
213+
```
214+
215+
浏览器加载上面代码时,就会向 Facebook 发出带有 Cookie 的请求,从而 Facebook 就会知道你是谁,访问了什么网站。
216+
217+
Cookie 的`SameSite`属性用来限制第三方 Cookie,从而减少安全风险。它可以设置三个值。
218+
219+
> - Strict
220+
> - Lax
221+
> - None
222+
223+
**(1)Strict**
224+
225+
`Strict`最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
226+
227+
```http
228+
Set-Cookie: CookieName=CookieValue; SameSite=Strict;
229+
```
230+
231+
这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
232+
233+
**(2)Lax**
234+
235+
`Lax`规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
236+
237+
```html
238+
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
239+
```
240+
241+
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
242+
243+
| 请求类型 | 示例 | 正常情况 | Lax |
244+
|-----------|:------------------------------------:|------------:|-------------|
245+
| 链接 | `<a href="..."></a>` | 发送 Cookie | 发送 Cookie |
246+
| 预加载 | `<link rel="prerender" href="..."/>` | 发送 Cookie | 发送 Cookie |
247+
| GET 表单 | `<form method="GET" action="...">` | 发送 Cookie | 发送 Cookie |
248+
| POST 表单 | `<form method="POST" action="...">` | 发送 Cookie | 不发送 |
249+
| iframe | `<iframe src="..."></iframe>` | 发送 Cookie | 不发送 |
250+
| AJAX | `$.get("...")` | 发送 Cookie | 不发送 |
251+
| Image | `<img src="...">` | 发送 Cookie | 不发送 |
252+
253+
设置了`Strict``Lax`以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
254+
255+
**(3)None**
256+
257+
Chrome 计划将`Lax`变为默认设置。这时,网站可以选择显式关闭`SameSite`属性,将其设为`None`。不过,前提是必须同时设置`Secure`属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
258+
259+
下面的设置无效。
260+
261+
```text
262+
Set-Cookie: widget_session=abc123; SameSite=None
263+
```
264+
265+
下面的设置有效。
266+
267+
```text
268+
Set-Cookie: widget_session=abc123; SameSite=None; Secure
269+
```
270+
184271
## document.cookie
185272

186273
`document.cookie`属性用于读写当前网页的 Cookie。
@@ -259,3 +346,8 @@ document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
259346
## 参考链接
260347

261348
- [HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies), by MDN
349+
- [Using the Same-Site Cookie Attribute to Prevent CSRF Attacks](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/)
350+
- [SameSite cookies explained](https://web.dev/samesite-cookies-explained)
351+
- [Tough Cookies](https://scotthelme.co.uk/tough-cookies/), Scott Helme
352+
- [Cross-Site Request Forgery is dead!](https://scotthelme.co.uk/csrf-is-dead/), Scott Helme
353+

0 commit comments

Comments
 (0)