浅谈Cookie和Session的区别
# 写在前面
Cookie 和 Session 都是时代的产物,现在已经有其它技术作为替代,且网上大多数文章都是些偏落后的信息,本文旨在启发大家甄别差异,并选用更为合理的方案。
# 结论
- Cookie 是浏览器存储机制,存在大小限制、安全性等问题,现在已经有 Web Storage API 和 IndexedDB 等作为替代方案。
- Session 是一种服务端存储方案,最初的方案是 SessionID 存在 Cookie 中,数据存在服务器内存中。但该方案已经不适合当前的分布式架构了。目前可以采用将 Session数据 加密的方式存于客户端实现。
- Session的功能在当前已经有很多替代方案,例如 JWT 、 OAuth 等...
# Cookie 和 Session 的区别
我从网上检索了几篇文章,总结下来两者直接差异集中在以下几点:
- 存储位置,Cookie 在浏览器,Session 在服务端。
- 存储大小,Cookie 约在4KB左右,Session 不限制。
- 安全性,因为 Session 在服务端,所以安全性更高。
- 存储时间,Cookie 可以设置有效期限制,Session 在浏览器关闭或者会话时失效。
但是以上的部分结论对我而言不太清晰,或者与我的认知有写相悖,例如:
- 存储位置,Cookie 在浏览器中这个没什么异议。但 Session 在服务端存储这件事,就值得一谈了。这里的服务端不清楚具体指什么?是内存,外存,还是三方存储??
- 存储大小,Session 在服务端,所以不限制。准确来讲,根据前一条提到的存储位置相关。
- 安全性风险,主要还是看破解损耗是否大于收益。
- 存储时间,针对 Session 存储位置的不同,存储时间应该有差异。不妨思考一个场景,从而反推一下存储问题,『用户一次登录以后,多久需要再次登录?』『如果服务器重启,用户是否需要重新登录』?
归纳一下以上的疑问,主要集中在下面两点:
- 如果服务器重启,用户是否需要重新登录?
- Session是单例模式的吗? 分布式部署时,Session 数据如何同步?
# Cookie 和 Session 是做什么的
众所周知 HTTP 本身是无状态的,服务端想要区分不同请求的身份,就需要接触浏览器请求时携带的 Cookie信息。
Cookie 是浏览器的一种存储机制,它可以在客户端存储少量的数据,在请求时携带这部分数据,用于帮助服务端识别用户身份等。服务端也可以在响应请求的时候,通过 Headers Set-Cookie 设置 Cookie,让浏览器存储。浏览器会通过域名区分 Cookie,同一个域名下的 Cookie 会被共享。
Cookie 也存在一些不足之处,例如:
- 存储于客户端,数据有被篡改的可能性,所以一般推荐只存一些非敏感数据。
- 存储大小有限制。根据 RFC 6265 标准描述,最低需要满足每个 Cookie 4096 字节,每个域名最少 50 条, 总 Cookie 最少支持 3000 个。
Session 是一种服务端存储机制,它通过在 Cookie 中设置 SessionID,在请求中携带 SessionID,让服务端识别用户身份。
常规的 Session 存储方案中,SessionID 存储在 Cookie 里,Session 的实际数据存储在服务端的内存中,但这种方式已经不适合当前的分布式架构,可以称得上是时代的眼泪了。
在分布式架构下,服务端往往会部署多台,如果 Session 存在内存中就不能共享数据了。为了解决这种问题,服务端也可以引用三方存储。
还有另外一种方案,即是把数据加密,整体存在 Cookie 中,这也是现行常见的一种 Session 存储方案。
但是不论是三方存储,还是加密存储,均有替代方案,或者适用的解决方案。例如 JWT、OAuth ,前者类似于加密存储的方案,后者在三方存储的基础上,将 B/S 场景拓展到多端层面。
注: Session 并不是浏览器提供的存储方案,它是借助 Cookie 实现的一种服务端存储机制。
# 浏览器存储机制
上文有提到,Session 并不是浏览器的存储机制,而是一种服务端的存储方案。在写这篇文章的时候,我也有问前端同事,对 Cookie 和 Session 的理解,他本能把 Session 当成了 SessionStorage。接下来着重讲一下浏览器提供的几种存储方式。
现在浏览器端常见的存储方式包括: Cookie、LocaStorage、SessionStorage 和 IndexedDB。其中LocaStorage、SessionStorage 并称 Web Storage。
Web Storage 之前浏览器存储采用的是 Cookie,Cookie 的特性上面已经提过了,这里不做赘述。
而在 Web Storage 中 LocaStorage 和 SessionStorage 的主要区别在于有效时长, SessionStorage 的有效时长为 Session 级别,当浏览器关闭后,则清除数据。
是不是听起来有点熟悉? "Cookie 可以设置有效期限制,Session 在浏览器关闭或者会话时失效。"
这个是之前提到的 Cookie 和 Session 的差异,之前的结论是有问题的。
IndexedDB 区别于前两种技术,它是用于结构化存储大量数据的API。
# 相关链接
Cookie 规范:RFC 6265 (opens new window) HTTP Cookie - mdn (opens new window)