真正“搞”懂HTTP协议09之这个饼干不能吃
我们在之前的文章中介绍HTTP特性的时候聊过,HTTP是无状态的,每次聊起HTTP特性的时候,我都会回忆一下从前辉煌的日子,也就是互联网变革的初期,那时候其实HTTP不需要有状态,就是个浏览页面,没有什么需要记录信息的地方,所以无状态完全符合当时的场景。
另外,无状态也给HTTP带来了不少的好处,正是因为无状态,这样服务器就没有状态差异,就可以很轻易的组成集群,当然,缺点就是无法支持需要记录状态的事务。为了解决这个缺点,Cookie就出现了。
一、这个饼干是什么?
Cookie的核心作用,其实就是让HTTP拥有记忆的能力,虽然服务器记不住,但是服务器可以根据HTTP提供的信息来做出相应的逻辑和判断。你大概可以这样理解,相当于服务器给每一个客户端都贴上了一个小纸条,当服务器把纸条设置好后,会发送给客户端,客户端每次传输HTTP数据的时候,就会把这个小纸条带上发给服务器,服务器就可以见人下菜碟了。
二、小饼干是怎么工作的?
关于Cookie的相关规范,并不在RFC2616或者RFC7230中,而是在RFC6265中,这份规范针对Cookie做了独立、详细的介绍。
Cookie的工作过程主要应用到了两个字段:响应头字段Set-Cookie和请求头字段Cookie。
当客户端像服务器第一次请求资源的时候,服务器会使用Set-Cookie来给客户端贴上一个标签,格式就是“key=value”这样,随着响应报文一起发送给浏览器。这样浏览器在下一次发送请求的时候会自动带上cookie数据,服务器发现欸?这次请求有Cookie,就知道不是首次请求,然后识别Cookie,为该用户提供个性化的服务。
当然,我们还可以使用多个Set-Cookie字段,来设置多个数据,让客户端携带更多的有用的信息。
要注意的是,Cookie与操作系统无关,是浏览器绑定的,当你换了浏览器,实际上相当于一个新的初次请求。
三、Cookie的属性
我们现在知道了,Cookie其实就是服务器委托客户端存储的一些数据,通常这些数据都是用来记录用户的关键信息。那么就需要一些额外的手段来保证Cookie的安全,这些手段就是Cookie的属性。我们下面就来看一下这些常用的有关于Cookie的属性有哪些。
首先,我们可以通过Expires 和 Max-Age设置Cookie的有效期,“Expires”俗称“过期时间”,用的是绝对时间点,可以理解为“截止日期”(deadline)。“Max-Age”用的是相对时间,单位是秒,浏览器用收到报文的时间点再加上 Max-Age,就可以得到失效的绝对时间。这两者可以同时出现,两者的失效时间可以一致,也可以不一致,但浏览器会优先采用 Max-Age 计算失效期。
其次,我们还可以设置Cookie的作用域,“Domain”和“Path”指定了 Cookie 所属的域名和路径,浏览器在发送 Cookie 前会从 URI 中提取出 host 和 path 部分,对比 Cookie 的属性。如果不满足条件,就不会在请求头里发送 Cookie。
使用这两个属性可以为不同的域名和路径分别设置不同的Cookie,比如/a用一个Cookie,/b用另外一个Cookie,当然通常都是一个“/”就完事了。
最后,我们要考虑的就是Cookie的安全性了,前端的同学们肯定知道,Cookie可以通过document.cookie获取,这样就导致了安全隐患,可能会导致XSS也就是跨站脚本攻击,从而窃取数据。HttpOnly属性就会告诉浏览器,此Cookie只能通过浏览器传输,禁止其它方式的访问,浏览器就会禁止任何API对cookie的访问,从而避免了XSS攻击。
再有,SameSite属性可以防范“跨站请求伪造”(XSRF)攻击,设置成“SameSite=Strict”可以严格限定 Cookie 不能随着跳转链接跨站发送,而“SameSite=Lax”则略宽松一点,允许 GET/HEAD 等安全方法,但禁止 POST 跨站发送。
还有一个属性叫“Secure”,表示这个 Cookie 仅能用 HTTPS 协议加密传输,明文的 HTTP 协议会禁止发送。但 Cookie 本身不是加密的,浏览器里还是以明文的形式存在。
四、Cookie的应用场景
其实Cookie最常见的应用场景就是身份识别,保存用户的登录信息,实现会话事务。
另一个常见的场景就是广告追踪,你上网的时候肯定看过很多的广告图片,这些图片背后都是广告商网站(例如 Google),它会“偷偷地”给你贴上 Cookie 小纸条,这样你上其他的网站,别的广告就能用 Cookie 读出你的身份,然后做行为分析,再推给你广告。这种 Cookie 不是由访问的主站存储的,所以又叫“第三方 Cookie”(third-party cookie)。如果广告商势力很大,广告到处都是,那么就比较“恐怖”了,无论你走到哪里它都会通过 Cookie 认出你来,实现广告“精准打击”。为了防止滥用 Cookie 搜集用户隐私,互联网组织相继提出了 DNT(Do Not Track)和 P3P(Platform for Privacy Preferences Project),但实际作用不大。
五、例子
我们先来看看简单的Cookie设置。代码也很简单:
res.setHeader("Set-Cookie", ["age=13", "name=zaking"]);
注意,如果你要设置多个Cookie的话,第二个参数要是个数组,我们看下效果:

这是第一次请求,然后我们刷新下页面:

你就能看到请求头中带上了cookie,我们还可以给每个cookie设置它的作用域和失效时间:
res.setHeader("Set-Cookie", [
"age=13; path=/; max-age=5",
"name=zaking; path=/set-cookie; max-age=10",
"hide=true; path=/else; max-age=1000",
]);
记得实验效果之前把上一次的cookie清空噢。然后我们看上面的代码,path限制了路径,所以当我们访问/set-cookie的页面的时候,其实只会有两个cookie,一个有效时间5秒,一个10秒。大家可以自己试下哦:

过了这个时间之后,你会发现一个Cookie都没有了。Cookie的属性中还有一个限制作用域的属性,叫做Domain,这个我就不试了,大家可以自行尝试一下噢。接下来我们看下,我们在页面中通过document.cookie来获取Cookie:
<body>
Cookie
</body>
<script>
console.log(document.cookie);
</script>
就这么简单,重启服务刷新页面后,可以看到控制台打印出了作用域范围内的Cookie。

我们加个HttpOnly再看看:
res.setHeader("Set-Cookie", [
"age=13; path=/; max-age=5",
"name=zaking; path=/set-cookie; max-age=10;HttpOnly",
"hide=true; path=/else; max-age=1000",
]);
结果就只剩下age了,完全符合我们的预期。

那么例子就到这里啦,还有一些我没写出来噢,比如SameSite和Secure。其实也并不复杂,我就是懒得写了。
六、总结
Cookie其实是有大名的,叫做Magic Cookie,意思是不透明的数据,跟饼干没啥关系噢。早期的Cookie都是存在磁盘上的文本文件,现在基本上是使用数据库存储,比如sqlite,存储的大小有一定的限制,是4k。
如果不指定Cookie生效实践,则会在浏览器关闭后无效,也叫做会话Cookie。历史上还有Set-Cookie2和Cookie2这样的字段,但是现在没用了。
真正“搞”懂HTTP协议09之这个饼干不能吃的更多相关文章
- 真正“搞”懂HTTP协议02之空间穿梭
时隔四年,这个系列鸽了四年,我终于觉得我可以按照自己的思路和想法把这个系列完整的表达出来了. 想起四年前,那时候还是2018年的六月份,那时候我还工作不到两年,那时候我翻译了RFC2616的部分内容, ...
- 真正“搞”懂http协议01—背景故事
去年读了<图解HTTP>.<图解TCP/IP>以及<图解网络硬件>但是读了之后并没有什么深刻的印象,只是有了一层模糊的脉络,刚好最近又接触了一些有关http的相关内 ...
- 真正“搞”懂HTTP协议03之时间穿梭
上一篇我们简单的介绍了一下DoD模型和OSI模型,还着重的讲解了TCP的三次握手和四次挥手,让我们在空间层面,稍稍宏观的了解了HTTP所依赖的底层模型,那么这一篇,我们来追溯一下HTTP的历史,看一看 ...
- 搞懂Redis协议RESP
RESP (REdis Serialization Protocal) Redis客户端和服务端之间通信的协议.它很简单,建立在TCP协议上,提供简单.高性能.可读性强的数据序列化的规范和语义. 5种 ...
- 搞懂分布式技术4:ZAB协议概述与选主流程详解
搞懂分布式技术4:ZAB协议概述与选主流程详解 ZAB协议 ZAB(Zookeeper Atomic Broadcast)协议是专门为zookeeper实现分布式协调功能而设计.zookeeper主要 ...
- 搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法
搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法 2PC 由于BASE理论需要在一致性和可用性方面做出权衡,因此涌现了很多关于一致性的算法和协议.其中比较著名的有二阶提交协议(2 Phas ...
- 搞懂分布式技术28:微服务(Microservice)那点事
搞懂分布式技术28:微服务(Microservice)那点事 微服务(Microservice)那点事 肥侠 2016-01-13 09:46:53 浏览58371 评论15 分布式系统与计算 微服务 ...
- [转帖]USB-C和Thunderbolt 3连接线你搞懂了吗?---没搞明白.
USB-C和Thunderbolt 3连接线你搞懂了吗? 2018年11月25日 07:30 6318 次阅读 稿源:威锋网 3 条评论 按照计算行业的风潮,USB Type-C 将会是下一代主流的接 ...
- 搞懂分布式技术21:浅谈分布式消息技术 Kafka
搞懂分布式技术21:浅谈分布式消息技术 Kafka 浅谈分布式消息技术 Kafka 本文主要介绍了这几部分内容: 1基本介绍和架构概览 2kafka事务传输的特点 3kafka的消息存储格式:topi ...
- 搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务
搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 初步认识RocketMQ的核心模块 rocketmq模块 rocketmq-broker:接受生产者发来的消息并存储(通过调用rocke ...
随机推荐
- 齐博x1会员中心如何加标签
点击查看大图 轻松几步,你可以做会员中心的界面 这是调用文章的 代码如下:会员中心的标签跟前台使用方法是一模一样的, 关键之处就是多了一项动态参数 union="uid" 在以往, ...
- 1.轮询、长轮询、websocket简介
一.轮询 前端每隔固定时间向后台发送一次请求,询问服务器是否有新数据 缺点: 延迟,需要固定的轮询时间,不一定是实时数据 大量耗费服务器内存和宽带资源,因为不停的请求服务器,很多时候 并没有新的数 ...
- 我的Spark学习笔记
一.架构设计 Driver根据用户代码构建计算流图,拆解出分布式任务并分发到 Executors 中去:每个Executors收到任务,然后处理这个 RDD 的一个数据分片子集 DAGSchedule ...
- 2022-11-02 Acwing每日一题
逆序对的个数 给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆 ...
- Pthread 并发编程(三)——深入理解线程取消机制
Pthread 并发编程(三)--深入理解线程取消机制 基本介绍 线程取消机制是 pthread 给我们提供的一种用于取消线程执行的一种机制,这种机制是在线程内部实现的,仅仅能够在共享内存的多线程程序 ...
- 数据结构篇——KMP算法
数据结构篇--KMP算法 本次我们介绍数据结构中的KMP算法,我们会从下面几个角度来介绍: 问题介绍 暴力求解 知识补充 Next示例 Next代码 匹配示例 匹配代码 完整代码 问题介绍 首先我们先 ...
- 关于Go你不得不知道的小技巧
目录 Go 箴言 Go 之禅 代码 使用 go fmt 格式化 多个 if 语句可以折叠成 switch 用 chan struct{} 来传递信号, chan bool 表达的不够清楚 30 * t ...
- SQL注入绕waf思路总结
1.关键字大小写混合绕过 关键字大小写混合只针对于小写或大写的关键字匹配技术-正则表达式,如果在匹配时大小写不敏感的话,就无法绕过.这是最简单的一个绕过技术. 例如:将union select混写成U ...
- 【SQL进阶】Day05:窗口函数
〇.概述 一.专用窗口函数 1.每类试卷得分前3名 自己写出来的部分 SELECT tag AS tid, uid AS uid, Rank AS ranking -- 如何确定排名 FROM exa ...
- python中文词云生成
一.词云 "词云"就是对网络文本中出现频率较高的"关键词"予以视觉上的突出,形成"关键词云层"或"关键词渲染",从而过滤 ...