当前位置: 首页 > news >正文

深入理解 Cookie 与 Session —— Web 状态保持详解与实战

一、为什么需要 Cookie 和 Session?

HTTP 协议是**无状态(Stateless)**的,这意味着:

  • 每次请求之间,服务器不会主动记住你是谁。

  • 用户在一次请求中登录了,下一次请求服务器依然当你是新访客。

  • 像购物车、个人中心、支付流程等功能无法在多次请求之间共享状态。

所以,状态保持技术的核心目标是:

让服务器在多个 HTTP 请求中“记住”客户端的身份和相关信息。

最常见的两种技术就是 CookieSession


二、Cookie —— 浏览器端的状态记录

1. 概念

       Cookie 是一小段存储在浏览器端的文本数据,由服务器生成并通过响应头 Set-Cookie 发送给浏览器保存。之后浏览器访问同一域名时会自动携带 Cookie 发送给服务器。

2. 工作原理

  1. 首次请求:浏览器访问服务器,服务器在响应头中设置 Cookie。

  2. 存储:浏览器将 Cookie 保存到本地文件(每个浏览器保存方式不同)。

  3. 后续请求:浏览器在请求头中自动带上 Cookie 信息。

  4. 服务器读取:服务器解析 Cookie,从而识别用户身份。

流程图示意:

[浏览器] --请求--> [服务器] 
[服务器] --Set-Cookie--> [浏览器保存] 
[浏览器] --携带Cookie请求--> [服务器读取并识别]

3. 示例

HTTP/1.1 200 OK
Set-Cookie: username=zhangsan; Path=/; HttpOnly; Max-Age=3600

下次请求:

GET /index.html HTTP/1.1
Cookie: username=zhangsan

4. Cookie 的关键属性

属性作用
Name=Value键值对数据
Domain指定 Cookie 生效的域名
Path指定 Cookie 生效的路径
Expires / Max-Age设置过期时间
HttpOnly防止 JavaScript 读取,增强安全性
Secure仅在 HTTPS 下传输

5. Cookie 的优缺点

优点:

  • 浏览器自动管理,无需额外代码处理传输。

  • 可以持久化存储(设置过期时间)。

缺点:

  • 存储容量小(单个约 4KB)。

  • 安全性差(数据明文存储在客户端,易被窃取或篡改)。

  • 每次请求都会携带 Cookie,会增加流量消耗。


三、Session —— 服务器端的状态记录

1. 概念

       Session 是一种服务器端存储的会话数据机制。
当用户第一次访问时,服务器会为其创建一个 Session,并分配一个唯一的 Session ID,将这个 ID 返回给浏览器保存(通常通过 Cookie)。

2. 工作原理

  1. 首次访问:服务器生成 Session 数据(例如登录状态、购物车内容),并生成唯一的 Session ID。

  2. 返回 Session ID:服务器通过 Cookie 将 Session ID 发给浏览器(如 JSESSIONID=xyz123)。

  3. 浏览器保存:浏览器保存 Session ID 到 Cookie。

  4. 后续请求:浏览器在请求中携带 Session ID,服务器根据该 ID 找到对应的 Session 数据。

3. 示例

Set-Cookie: JSESSIONID=xyz123; Path=/; HttpOnly

后续请求:

GET /cart HTTP/1.1
Cookie: JSESSIONID=xyz123

4. Session 特性

  • 存储位置:服务器内存 / 数据库 / 分布式缓存(如 Redis)。

  • 生命周期:默认 30 分钟(可配置)。

  • 容量限制:取决于服务器内存,理论上可存储较大数据。

  • 安全性:数据不直接暴露给客户端,安全性高。


四、Cookie 与 Session 的关系

实际上,Session 通常依赖 Cookie 来保存 Session ID

  • Cookie 中只保存一个 Session ID

  • 具体的用户数据(登录状态、购物车等)存放在服务器的 Session 对象中。

这种方式结合了两者的优点:

  • 减少 Cookie 存储压力。

  • 提升安全性(敏感数据不放在客户端)。


五、Cookie 与 Session 的对比

对比项CookieSession
存储位置客户端(浏览器)服务器端
安全性易被窃取或篡改(需加密)高,数据不暴露给客户端
存储容量单个 ≤ 4KB受服务器内存限制
生命周期可设置过期时间默认短时存储,可配置
性能影响占用客户端空间,增加网络流量占用服务器内存
使用场景保存非敏感、需要持久化的数据保存敏感数据(如登录信息)

六、实际开发中的应用

1. 用户登录流程(Session 版)

  1. 用户输入账号密码并提交。

  2. 服务器验证成功后,创建 Session,保存用户信息。

  3. Session ID 写入 Cookie。

  4. 后续请求带上 Session ID,服务器即可识别用户。

2. 用户登录流程(Cookie 版)

  1. 用户输入账号密码并提交。

  2. 服务器验证成功后,将用户信息加密后写入 Cookie。

  3. 后续请求直接解析 Cookie 获取用户信息(需注意安全风险)。


七、安全性问题与防护措施

Cookie 和 Session 都是状态保持机制,但如果使用不当,可能被攻击者利用。常见问题包括:

1. Cookie 劫持(Session Hijacking)

原理:攻击者获取了你的 Cookie(尤其是 Session ID),就能冒充你的身份。
场景:公共 WiFi 抓包、XSS 注入读取 Cookie。
防护措施

  • 使用 HTTPS 传输,防止中间人截获。

  • 设置 HttpOnly,防止 JS 脚本读取 Cookie。

  • 设置 Secure,仅允许在 HTTPS 下传输。

2. Cookie 重定义(Cookie Overwriting)

原理:攻击者在客户端或通过响应头写入相同名称的 Cookie,从而覆盖原有 Cookie 内容,导致身份被冒用或数据被篡改。
场景

  • 同一域名下的不同子域篡改 Cookie。

  • 恶意响应头设置同名 Cookie 覆盖原值。
    防护措施

  • 为 Cookie 设置明确的 DomainPath 限制作用范围。

  • 对 Cookie 值进行签名和验证,防止篡改。

3. Session 固定攻击(Session Fixation / Session 重定义)

原理:攻击者提前获取或制造一个合法的 Session ID,然后诱导受害者使用该 Session ID。一旦受害者登录,攻击者就能使用相同的 Session ID 登录到受害者的账号。
流程示例

  1. 攻击者访问网站,获取一个合法的 Session ID=abc123

  2. 攻击者将该 Session ID 发送给受害者(通过 URL、恶意链接等方式)。

  3. 受害者在该 Session ID 下登录。

  4. 攻击者用相同的 Session ID 就能直接登录受害者账号。

防护措施

  • 登录成功后重新生成 Session ID(关键)。

  • 不允许通过 URL 传递 Session ID。

  • 对 Session 设置较短的过期时间,并限制 IP/UA 绑定。

4. Session 过期处理不当

原理:Session 过期后,如果前端没有提示重新登录,可能导致用户操作失败,体验差。
防护措施

  • 后端返回特定状态码(如 401/440)。

  • 前端检测到状态码后跳转到登录页,并可选保存用户输入内容。


八、Java 中的 Cookie 与 Session 实战

       在 Java Web(Servlet)开发中,Cookie 和 Session 是内置支持的,我们可以很方便地使用它们。

1. Cookie 的使用

1.1 设置 Cookie
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;public class SetCookieServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {// 创建 Cookie 对象Cookie cookie = new Cookie("username", "zhangsan");// 设置 Cookie 过期时间(秒),这里设置 1 小时cookie.setMaxAge(60 * 60);// 设置作用路径(默认是当前项目路径)cookie.setPath("/");// 添加到响应response.addCookie(cookie);response.getWriter().write("Cookie 已设置!");}
}
1.2 读取 Cookie
public class GetCookieServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {Cookie[] cookies = request.getCookies();if (cookies != null) {for (Cookie c : cookies) {if ("username".equals(c.getName())) {response.getWriter().write("读取到 Cookie:username=" + c.getValue());}}} else {response.getWriter().write("没有找到 Cookie");}}
}

2. Session 的使用

2.1 创建与存储 Session 数据
public class SetSessionServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {// 获取 Session,没有则创建HttpSession session = request.getSession();// 存储数据到 Sessionsession.setAttribute("user", "zhangsan");// 设置 Session 过期时间(秒)session.setMaxInactiveInterval(30 * 60);response.getWriter().write("Session 已存储!");}
}
2.2 获取 Session 数据
public class GetSessionServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {HttpSession session = request.getSession(false); // false 表示没有就不创建if (session != null) {String user = (String) session.getAttribute("user");if (user != null) {response.getWriter().write("Session 中的 user = " + user);} else {response.getWriter().write("Session 中没有 user 数据");}} else {response.getWriter().write("Session 不存在");}}
}

3. 小技巧与注意事项

  • Session 默认使用 Cookie 存 Session ID(JSESSIONID),如果禁用 Cookie,可以通过 URL 重写:

response.encodeURL("myServlet");
  • Session 清除

session.invalidate();
  • Cookie 安全性:对于敏感信息,应加密后再存储,或者仅存 Session ID。

  • Session 分布式存储:在分布式环境中使用 Redis 等中间件来存储 Session,实现会话共享。


九、总结

  1. Cookie 适合存放少量非敏感数据,可跨会话持久化。

  2. Session 安全性高,适合保存登录等敏感信息。

  3. 最佳实践:用 Cookie 存 Session ID,核心数据放 Session。

  4. Java Web 开发 内置了 Cookie 和 Session API,用法简单高效。

  5. 在安全上,需防范 Cookie 重定义Session 固定攻击Cookie 劫持 等问题。

http://www.lryc.cn/news/620332.html

相关文章:

  • SpringBoot 整合 Langchain4j 系统提示词与用户提示词实战详解
  • JavaWeb(05)
  • TCP客户端Linux网络编程设计详解
  • 人工智能——CNN基础:卷积和池化
  • HiSmartPerf使用WIFI方式连接Android机显示当前设备0.0.0.0无法ping通!设备和电脑连接同一网络,将设备保持亮屏重新尝试
  • SAP Valuation Category在制造业成本核算中的使用场景与配置方案
  • 基于C语言基础对C++的进一步学习_C和C++编程范式、C与C++对比的一些补充知识、C++中的命名空间、文件分层
  • window显示驱动开发—多平面覆盖 VidPN 呈现
  • 看懂 Linux 硬件信息查看与故障排查
  • 力扣42:接雨水
  • 人工智能入门①:AI基础知识(上)
  • Python图像处理基础(十三)
  • 《工程封装》(Python)
  • 网络安全合规6--服务器安全检测和防御技术
  • 3.Ansible编写和运行playbook
  • 3DM游戏运行库合集离线安装包下载, msvcp140.dll丢失等问题修复
  • ESP32_STM32_DHT20
  • 三极管的基极为什么需要下拉电阻
  • Vue3从入门到精通:4.1 Vue Router 4深度解析与实战应用
  • vue实现模拟 ai 对话功能
  • JS的学习5
  • vue修改element的css属性
  • 决策树回归:用“分而治之”的智慧,搞定非线性回归难题(附3D可视化)
  • 北京JAVA基础面试30天打卡09
  • uniapp授权登录
  • 硬件工程师八月实战项目分享
  • 8.13迎来联动:PUBG布加迪,新版本37.1内容资讯!低配置也能飙车吃鸡!
  • 谈一些iOS组件化相关的东西
  • 【Golang】 Context.WithCancel 全面解析与实战指南
  • CAN仲裁机制的原理