作者 | 个推 web 前端架构师 姜季廷
在技术面试中,经常被问到“说说 Cookie 和 Session 的区别”,大家都知道,Session 是存储在服务器端的,Cookie 是存储在客户端的,然而如果让你更详细地说明,你能说出几点?今天个推君就和大家谈谈“Cookie 和 Session”的那些事儿。
Cookie 是什么?
从它的词语本身含义来看: Cookie: n. 饼干;小甜点 N-COUNT A cookie is a piece of computer software which enables a website you have visited to recognize you if you visit it again. 再次访问某一网站时,能令网站识别访问人的计算机软件。
Cookie 是客户端保存用户信息的一种机制,用来记录用户的一些信息。如何识别特定的客户呢?cookie 就可以做到。每次 HTTP 请求时,客户端都会发送相应的 Cookie 信息到服务端。它的过期时间可以任意设置,如果你不主动清除它,在很长一段时间里面都可以保留着,即便这之间你把电脑关机了。
既然它是存储在客户端的,换句话说通过某些手法我就可以篡改本地存储的信息来欺骗服务端的某些策略,那该怎么办呢?我们先按下不表,来看看另外一位朋友 —— Session。
Session 是什么?
同样,我们先来看看释义: Session: 普通释义:n. 会议;(法庭的)开庭;(议会等的)开会;学期;讲习会 计算机释义:会话
Session 是在无状态的 HTTP 协议下,服务端记录用户状态时用于标识具体用户的机制。它是在服务端保存的用来跟踪用户的状态的数据结构,可以保存在文件、数据库或者集群中。在浏览器关闭后这次的 Session 就消失了,下次打开就不再拥有这个 Session。其实并不是 Session 消失了,而是 Session ID 变了,服务器端可能还是存着你上次的 Session ID 及其 Session 信息,只是他们是无主状态,也许一段时间后会被删除。
实际上 Cookie 与 Session 都是会话的一种方式。它们的典型使用场景比如“购物车”,当你点击下单按钮时,服务端并不清楚具体用户的具体操作,为了标识并跟踪该用户,了解购物车中有几样物品,服务端通过为该用户创建 Cookie/Session 来获取这些信息。
如果你的站点是多节点部署,使用 Nginx 做负载均衡,那么有可能会出现 Session 丢失的情况(比如,忽然就处于未登录状态)。这时可以使用 IP 负载均衡(IP 绑定 ip_hash,每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 Session 的问题),或者将 Session 信息存储在集群中。在大型的网站中,一般会有专门的 Session 服务器集群,用来保存用户会话,这时可以使用缓存服务比如 Memcached 或者 Redis 之类的来存放 Session。
目前大多数的应用都是用 Cookie 实现 Session 跟踪的。第一次创建 Session 时,服务端会通过在 HTTP 协议中反馈到客户端,需要在 Cookie 中记录一个 Session ID,以便今后每次请求时都可分辨你是谁。有人问,如果客户端的浏览器禁用了 Cookie 怎么办?建议使用 URL 重写技术进行会话跟踪,即每次 HTTP 交互,URL 后面都被附加上诸如 sid=xxxxx 的参数,以便服务端依此识别用户。
换个姿势~
客户端和服务端之间的通信交流,可以这样简单理解: 比如当你在个推技术分享沙龙上觉得某位讲师讲得很好,在会后问了他几个问题,他对你这些问题进行了回答,这就是一个会话。但这个讲师太受欢迎,于是工作人员收集问题,并给每个提问者一个号码牌,讲师按照号码牌依次给出相应解答并告诉相应的人。这就是 Session。一段时间后,当你再次遇见这位讲师,他发现你身上有上次回复你的答案,知晓你是那个好学的程序猿。于是你欣喜若狂,哇塞,讲师居然认出我了,这就是 Cookie,你的小甜点。客户端好比听课的技术爱好者,服务端就是这位讲师。
Cookie 还可以在一些方便用户的场景下使用。比如你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以被写到 Cookie 里面,当访问网站时,网站页面的脚本可以读取这个信息,自动填写用户名,方便用户使用,给用户一点甜头。
总结语:
1、Cookie 在客户端(浏览器),Session 在服务器端。 2、Cookie 的安全性一般,他人可通过分析存放在本地的 Cookie 并进行 Cookie 欺骗。在安全性第一的前提下,选择 Session 更优。重要交互信息比如权限等就要放在 Session 中,一般的信息记录放 Cookie 就好了。 3、单个 Cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 Cookie。 4、Session 可以放在 文件、数据库或内存中,比如在使用 Node 时将 Session 保存在 redis 中。由于一定时间内它是保存在服务器上的,当访问增多时,会较大地占用服务器的性能。考虑到减轻服务器性能方面,应当适时使用 Cookie。 5、Session 的运行依赖 Session ID,而 Session ID 是存在 Cookie 中的,也就是说,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 Session ID)。 6、用户验证这种场合一般会用 Session。因此,维持一个会话的核心就是客户端的唯一标识,即 Session ID。
题外话,那么话说 Session Cookie 能被篡改么? 理论上可以,只要改变了连接时的 Session ID 就可以了~