“Cookie 是会员卡,Session 是保险柜。”
如果说 Cookie 是你随身携带的会员卡,记录着你的偏好与身份;
那么 Session 就是咖啡馆后台的保险柜,锁着你的消费记录、积分和隐私信息。
两者协同工作,共同构建了 Web 应用的“记忆系统”。
一、核心概念回顾技术
定义
类比
Cookie
存储在浏览器中的小型文本数据,随每次请求自动发送给服务器
一张随身携带的会员卡
Session
存储在服务器中的用户会话数据,通过一个唯一的 Session ID 与客户端关联
咖啡馆后台的专属档案柜
二、Cookie 深度解析:浏览器的“记忆贴纸”2.1 Cookie 的本质Cookie 并非“甜点”,而是 HTTP 协议中用于状态管理的机制。它是一段键值对文本,通过 Set-Cookie 响应头由服务器下发,浏览器自动在后续请求中通过 Cookie 请求头回传。
📊 Cookie 核心属性一览:属性
说明
安全建议
Name
Cookie 名称(唯一标识)
避免敏感命名(如 password)
Value
存储的值(字符串)
敏感信息不要明文存储
Expires/Max-Age
过期时间
设置合理有效期,避免长期驻留
Domain
作用域名
精确设置,防止跨域泄露
Path
作用路径
限制路径范围,缩小影响面
Secure
仅 HTTPS 传输
生产环境必须开启
HttpOnly
禁止 JS 访问
防止 XSS 攻击,强烈推荐
SameSite
防止 CSRF 攻击
推荐设为 Lax 或 Strict
2.2 Spring Boot 中操作 Cookie✅ 设置 Cookie代码语言:java复制@GetMapping("/set-cookie")
public String setCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("theme", "dark");
cookie.setPath("/"); // 全站生效
cookie.setMaxAge(60 * 60 * 24); // 24小时
cookie.setHttpOnly(true); // 禁止 JS 读取
cookie.setSecure(true); // 仅 HTTPS
cookie.setSameSite("Lax"); // 防 CSRF
response.addCookie(cookie);
return "Cookie 已设置";
}✅ 读取 Cookie代码语言:java复制@GetMapping("/get-cookie")
public String getCookie(@CookieValue(value = "theme", defaultValue = "light") String theme) {
return "当前主题:" + theme;
}✅ 删除 Cookie代码语言:java复制@GetMapping("/delete-cookie")
public String deleteCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("theme", "");
cookie.setMaxAge(0); // 立即过期
cookie.setPath("/");
response.addCookie(cookie);
return "Cookie 已删除";
}三、Session 深度解析:服务器的“私人保险柜”3.1 Session 的工作原理用户首次访问 → 服务器创建 Session 对象生成唯一 JSESSIONID → 存入 Cookie 发送给浏览器后续请求 → 浏览器自动携带 JSESSIONID服务器查找 → 根据 JSESSIONID 定位 Session 数据🔐 关键点:Session 数据存在服务器内存(或 Redis 等外部存储),客户端只持有“钥匙”(Session ID),数据本身不会暴露。
3.2 Spring Boot 中操作 Session✅ 存储数据到 Session代码语言:java复制@RestController
public class LoginController {
@PostMapping("/login")
public String login(@RequestParam String username,
@RequestParam String password,
HttpSession session) {
// 模拟登录验证
if ("admin".equals(username) && "123456".equals(password)) {
User user = new User(username, "高级会员");
session.setAttribute("user", user);
session.setAttribute("loginTime", new Date());
return "登录成功!";
}
return "用户名或密码错误";
}
}✅ 读取 Session 数据代码语言:java复制@GetMapping("/profile")
public String profile(HttpSession session) {
User user = (User) session.getAttribute("user");
if (user == null) {
return "请先登录";
}
return "欢迎," + user.getUsername() + "!";
}✅ 配置 Session 过期时间代码语言:javascript代码运行次数:0运行复制# application.properties
server.servlet.session.timeout=1800 # 30分钟(秒)或在 web.xml 中配置:
代码语言:xml复制
四、Cookie vs Session:全方位对比对比维度
Cookie
Session
存储位置
🖥️ 客户端(浏览器)
🖥️ 服务器端(内存/Redis)
数据大小
⚠️ 限制约 4KB
✅ 理论无限制(受服务器资源影响)
生命周期
可设置长期有效(如 1 年)
默认 30 分钟,可配置,关闭浏览器不立即失效
安全性
❌ 较低(可被窃取、篡改)
✅ 较高(数据在服务器,ID 可加密)
性能影响
✅ 每次请求自动携带,增加请求头大小
✅ 服务器需维护 Session 存储,内存压力大
跨域支持
⚠️ 受同源策略限制,Domain 可跨子域
❌ 默认不支持跨域(需额外配置)
服务器依赖
✅ 无状态,可扩展性好
✅ 集群环境下需 Session 共享(如 Redis)
典型用途
用户偏好(主题、语言)
跟踪ID(GA、广告)
非敏感标识(用户ID)
用户登录状态
购物车
敏感信息(权限、积分)
防重复提交Token
五、实战选择指南:什么时候用哪个?✅ 推荐使用 Cookie 的场景:场景
示例
用户偏好设置
主题颜色、字体大小、语言选择
非敏感标识
用户ID(非密码)、设备ID
第三方跟踪
Google Analytics、广告追踪
轻量级状态保持
访问次数统计、新手引导状态
🛠️ 优化建议:
使用 HttpOnly + Secure + SameSite 提升安全避免存储敏感信息合理设置过期时间,避免 Cookie 泛滥✅ 推荐使用 Session 的场景:场景
示例
用户身份认证
登录状态、JWT Token 存储(可选)
购物车管理
商品列表、优惠券信息
表单防重
提交Token、验证码
敏感业务数据
权限信息、支付状态、订单草稿
🛠️ 优化建议:
集群部署时使用 Redis 或 数据库 存储 Session设置合理的过期时间,避免内存泄露敏感操作可结合 Token 二次验证六、安全攻防实战:常见攻击与防御🔒 1. XSS(跨站脚本攻击) → 目标:窃取 Cookie攻击方式:注入恶意脚本读取 document.cookie防御手段:✅ Cookie 设置 HttpOnly = true✅ 输入内容进行 HTML 转义✅ 使用 CSP(内容安全策略)🔒 2. CSRF(跨站请求伪造) → 目标:伪造用户请求攻击方式:诱导用户在已登录状态下访问恶意网站,发起请求防御手段:✅ Cookie 设置 SameSite = Lax/Strict✅ 使用 Anti-CSRF Token(存储在 Session 中)✅ 验证 Referer 头🔒 3. Session 劫持 → 目标:窃取 Session ID攻击方式:通过网络嗅探或 XSS 获取 JSESSIONID防御手段:✅ 强制 HTTPS(Secure = true)✅ Session ID 高强度随机生成✅ 登录后重新生成 Session ID(防止会话固定攻击)✅ 设置较短过期时间七、现代演进:JWT 与 Token 化会话随着前后端分离和微服务架构的普及,基于 Token 的无状态会话(如 JWT)逐渐流行:
技术
特点
JWT (JSON Web Token)
自包含、无状态、可签名加密,适合分布式系统
OAuth2 / OpenID Connect
第三方授权登录标准,支持单点登录(SSO)
🔄 趋势:
传统 Session → JWT Token + Redis 缓存验证 → 更适合云原生和高并发场景。
八、总结:Cookie 与 Session 的“黄金搭档”角色
Cookie
Session
定位
客户端“记忆卡”
服务器“保险柜”
优势
轻量、可持久化
安全、可存储大数据
劣势
安全风险、容量小
服务器压力、需共享
最佳实践
存储非敏感标识
存储核心状态数据
✅ 终极建议:
Cookie + Session 结合使用:用 Cookie 存储 JSESSIONID,用 Session 存储用户数据。高并发场景:Session 存储到 Redis,提升性能与可用性。前后端分离:考虑使用 JWT,实现无状态认证。九、面试高频题1. Cookie 和 Session 的区别?从存储位置、安全性、生命周期、性能等维度回答。
2. 如何防止 Session 劫持?HTTPS、HttpOnly、定期更换 Session ID、SameSite 等。
3. 分布式环境下如何实现 Session 共享?Redis、数据库、粘性 Session(Sticky Session)等方案。
4. JWT 和 Session 有什么区别?JWT 无状态、自包含;Session 有状态、依赖服务器存储。
结语Cookie 与 Session 并非“非此即彼”的选择,而是协同作战的黄金搭档。
理解它们的原理、差异与安全边界,才能在不同场景下做出最优决策,构建既安全又高效的 Web 应用。
🎯 记住:
不要把保险柜的钥匙(Session ID)随便乱放更不要把贵重物品(敏感数据)贴在衣服上(Cookie)掌握会话管理,你就能真正掌控用户的“数字足迹”,打造流畅、安全的用户体验。