note
note copied to clipboard
Http-cookie
再看cookie
- npm cookie库,
- nodejs/express/客户端 如何操作cookie,
- cookie间隔为啥是'; '
- https://github.com/30-seconds/30-seconds-of-code/blob/master/snippets/parseCookie.md
- cookie跨域问题
- 历史:引入背景,和localstorage, sessionstorage差异
- cookie的安全
一、概述
1.1 什么是Cookie
Cookie是服务器存储在客户端的数据(小段文本)。 这是见过最好的描述,你品,你细品。
1.2 为啥需要Cookie
HTTP是stateless,Cookie是实现HTTP State Management Mechanism。
- HTTP客户端通过Cookie让HTTP Server识别自己;
- Cookie存储在HTTP客户端,HTTP请求头
Cookie传给给HTTP服务端; - HTTP服务端通过响应头
Set-Cookie管理HTTP客户端存储的Cookie; - Cookie数据需要在HTTP会话中传递,所以Cookie数据必须小。
1.3 Cookie的限制
大小、数量:
- 为了防止滥用cookie导致HTTP请求头过大,各浏览器对一个domain的cookie数据和cookie大小都有限制。
-
Don't exceed 50 cookies per domain, and don't exceed 4093 bytes per domain
- 如果只是想实现浏览器端的数据持久化,可以使用其他Web存储(localstorage, sessionstorage,indexDB等)
字符集
- cookie的
name和value是用户自定义的,但是需要都采用US-ASCII字符集; - 有些字符不能作为
name如空格,tab, ) < > @ , ; : \ " / [ ] ? = { }等 - 有些字符作为
value需要转移; 如分号,空格,其他非US-ASCII字符集的字符。 - 一般通过
decodeURIComponent对value进行转义;
二、Cookie的构成
2.1 Cookie属性
1. 核心属性:name和value属性
2. 有效期属性:Expires和Max-Age
- session Cookie:没有指定有效期的cookie
- 持久化cookie:指定有效期的cookie
3. 作用域控制属性:Domain和Path
4. 安全控制属性:Secure和HttpOnly,SameSite
-
HttpOnly防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击。 -
Secure防止 Cookie 在传输过程中被窃取和篡改. -
SameSite可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。
2.2 HTTP响应Set-Cookie头
- HTTP服务向客户端发送
cookie数据,一个Set-Cookie对应一个cookie数据; - Cookie各个属性通过
;隔开(其中分号后面是0个或多个空格);
2.3 HTTP请求Cookie头
- 客户端向服务发送当前domain可以访问的并且有效的cookie列表。多个cookie通过
;隔开(其中空格可选,0个或者多个);
三、use-cookies-securely
-
domain不能用作安全措施;
四、跨域
Cookie并不严格遵循浏览器同源策略,而是同站(SameSite),即主域一致就可以共享。
- 子Domain可以访问父Domain下的cookie(反之不行,兄弟domain也不行);
- Cookie的作用域跟端口无关,即不同端口的相同域名和path可以共享cookie。
五、Cookie 与 Session 的区别
参考
浏览器操作Cookie
- 客户端操作Cookie受限比较多些(作用域,httpOnly)。
-
document.cookie表示当前文档能访问的cookie(这也是为啥cookie熟悉不是在window对象下)。
document.cookie
// 读所有的cookies
allCookies = document.cookie;
// 写单个cookie
document.cookie = newCookie;
-
document.cookie作为右值时,则返回当前domain下可以访问且有效的cookie(key-value对)字符串列表。
"_test_k1=hello1; _test_k3=world3; _test_session=session%20cookie;"
-
document.cookie作为左值时,表示对单个cookie进行操作(新增,编辑,删除)。 - 不得不说通过
document.cookie操作cookie挺麻烦的。
- 不能读取单个cookie;
- 写cookie必须先转成字符串,缺乏语义话的操作API;
- 不过
document.cookie倒是很方便在HTTP请求头添加Cookie头时取值。
提取单个cookie值
document.cookie返回的是所有的cookie列表字符串,如果要读取单个cookie一般有两种方式:
- 利用正则表达式
- 先把
document.cookie转成对象,再读取。 30-seconds-of-code parseCookie
const parseCookie = str =>
str
.split(';')
.map(v => v.split('='))
.reduce((acc, v) => {
acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
return acc;
}, {});
社区也有其他cookie解析库npm cookie
服务端操作Cookie
1. 基于Nodejs HTTP服务端
- 采用HTTP的语法规则+借助第三方的cookie操作库
2. 基于Expressjs库 HTTP服务端
expressjs提供了更加语义化的操作API。
- Express还支持对cookie的
value进行加密、解密处理(缺点就是影响性能)