Session 与 Cookie 区别
Cookie 数据存放在客户的浏览器上,Session 数据放在服务器上。
Cookie 不是很安全,别人可以分析存放在本地的 Cookie 并进行 Cookie 欺骗,考虑到安全应当使用 Session。
Session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用 Cookie。
单个 Cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 Cookie。
这四条是区别清单,但清单回答不了两个更深的问题:Session 为什么需要 Cookie 配合(它们不是对立关系而是协作关系),以及分布式环境下 Session 怎么办。把这两点补上,这个题目才算答完。
本质:HTTP 无状态与状态保持
HTTP 是无状态协议:服务器处理完请求就忘记你是谁。但购物车、登录态都需要”记住你”。两种记忆路线:
- Cookie:把状态记在客户端。服务器通过
Set-Cookie响应头下发数据,浏览器存储并在后续请求自动携带Cookie头 - Session:把状态记在服务端。服务器为每个会话创建一块内存/存储,客户端只持有一个会话标识(sessionId)
所以严格说 Session 机制依赖 Cookie 传递 sessionId(Cookie 名常为 JSESSIONID);浏览器禁用 Cookie 时退化为 URL 重写(;jsessionid=xxx)。二者是”凭证在客户端、档案在服务端”的配合,而非二选一。
差异全景
| 维度 | Cookie | Session |
|---|---|---|
| 存储位置 | 浏览器 | 服务器(内存/Redis) |
| 安全性 | 客户端可见可改,需防伪造 | 数据不出服务端,仅凭证在外 |
| 容量 | 单条 4KB、每域约 20-50 条 | 受服务器内存/存储限制 |
| 生命周期 | 可设过期时间,持久化到磁盘 | 会话级,超时(默认约 30 分钟)失效 |
| 服务器开销 | 无状态,天然水平扩展 | 有状态,多节点需共享 |
| 跨域 | 受 SameSite/域限制 | sessionId 可放 Header/Token 跨端 |
安全细节:Cookie 欺骗怎么防
“Cookie 不安全”的准确含义是:客户端存储的内容可被读取与篡改。对策分层:
- 敏感数据不入 Cookie:Cookie 只放不透明凭证(sessionId 或签名 Token),真实状态在服务端
- HttpOnly:禁止 JS 读取,防 XSS 窃取会话凭证
- Secure + SameSite:仅 HTTPS 传输、限制跨站携带,防嗅探与 CSRF
- 签名/加密:若必须放客户端(如记住偏好),加 HMAC 签名防篡改
分布式下的 Session 困境与出路
单机 Session 在多实例部署时立刻出问题:请求被负载均衡到另一台机器,会话丢失。三条出路:
- Session 复制:节点间同步会话,写放大严重,集群规模受限
- 粘性会话(sticky):负载均衡按 sessionId 哈希固定节点,节点宕机会话仍丢
- Session 外置(主流):会话存 Redis,所有节点共享,配合 TTL 自动过期——本质是把 Session 变成”服务端管理的分布式 Cookie 存储”
再进一步就是 Token 化(JWT):服务端不再存状态,把用户信息签名后放客户端(Authorization 头或 Cookie),服务端只验签。代价是注销与续期难(令牌已发出)、体积大、泄露后无法立即失效(需黑名单补偿)。选型口诀:要能随时踢人/改权限用 Session+Redis;要无状态横向扩展/跨端用 JWT。
实践建议
- 登录态默认 Session(或 Redis 会话)+ HttpOnly Cookie;前后端分离可改 JWT 放 Header
- Cookie 里永远不放明文用户 ID/邮箱等可枚举信息
- 会话超时与滑动续期策略要明确(金融类短超时+操作重验)
- 记住我(remember-me)用独立长时效签名 Cookie,与登录会话分离
Session 与 Cookie 的区别不在”谁存哪”一句话,而在状态放在哪一侧所带来的安全、扩展、容量连锁差异;理解这条因果链,清单里的每一条都能自己推出来。











