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

Cookie 与 Session 全解析:从属性原理到核心逻辑,吃透 Web 状态保持

   学习目标:

  • 学习

        在 Web 开发中,“网站如何记住用户” 是绕不开的核心问题 —— 为什么登录后关闭浏览器,下次打开还能直接访问?为什么购物车商品不会随页面刷新消失?答案就藏在 Cookie 和 Session 里。今天我们从属性原理、使用条件、工作流程到核心逻辑,用大白话 + 实战案例彻底拆解,不管是开发还是面试,都能让你心里有底。

一、先搞懂基础:为什么需要 Cookie 和 Session?

Web 协议(HTTP)本身是 “无状态” 的 —— 就像你每次去咖啡店,店员都不认识你,需要重新说一遍需求。但实际场景中,我们需要网站 “记住” 用户(比如登录状态、购物车、偏好设置),这时候就需要 Cookie 和 Session 这两个 “记忆工具”:

  • Cookie:存放在用户浏览器的 “小纸条”,记录简单信息;
  • Session:存放在服务器的 “专属账本”,记录敏感 / 复杂信息。两者配合工作,实现 Web 的 “状态保持”。

二、Cookie:浏览器端的 “记忆纸条”—— 属性原理 + 流程

Cookie 是服务器发送给浏览器的小型文本数据,浏览器会以键值对(Key-Value)形式存储在本地,下次访问同一服务器时自动携带。我们从核心属性、工作流程、使用条件三方面拆解。

1. Cookie 的核心属性:决定 “怎么存、存多久、安不安全”

每个 Cookie 都有一组属性,这些属性直接影响它的行为

实战案例:登录时设置安全的 Cookie后端(Java)代码示例,给 “用户登录令牌” 设置关键属性:

java

运行

Cookie loginCookie = new Cookie("user_token", "abc123xyz");
loginCookie.setHttpOnly(true); // 禁止JS读取,防XSS
loginCookie.setSecure(true);   // 仅HTTPS传输,防拦截
loginCookie.setSameSite("Lax");// 防CSRF,平衡安全与体验
loginCookie.setMaxAge(60*60*24*7); // 存活7天(持久Cookie)
loginCookie.setDomain(".a.com");   // 允许子域名(如api.a.com)访问
loginCookie.setPath("/");          // 全域名路径可访问
response.addCookie(loginCookie);   // 发送给浏览器

2. Cookie 的工作流程:4 步实现 “记住用户”

以 “用户首次登录电商网站” 为例,看 Cookie 如何工作:

  1. 用户发起请求:用户在浏览器输入账号密码,点击登录,向服务器发送 HTTP 请求;
  2. 服务器生成 Cookie:服务器验证账号密码正确后,生成包含 “用户标识” 的 Cookie(如user_id=123),并设置 HttpOnly、Secure 等属性,通过 HTTP 响应的Set-Cookie头部发给浏览器;
    • 响应头示例:Set-Cookie: user_token=abc123xyz; HttpOnly; Secure; SameSite=Lax; Max-Age=604800
  3. 浏览器存储 Cookie:浏览器解析Set-Cookie头部,将 Cookie 以文件形式存到本地(如 Chrome 存到本地数据库);
  4. 后续请求自动携带:用户下次访问该电商网站(如查看购物车),浏览器会自动读取本地 Cookie,通过 HTTP 请求的Cookie头部发给服务器;
    • 请求头示例:Cookie: user_token=abc123xyz; theme=dark
  5. 服务器识别用户:服务器解析Cookie头部,通过user_token确认用户身份,返回对应的个性化内容(如显示用户的购物车商品)。

3. Cookie 的使用条件:什么时候该用 Cookie?

Cookie 适合存储少量、非敏感、需要长期保留的信息,典型场景:

  • 记录用户偏好(如网站主题、字体大小、默认语言);
  • 未登录用户的购物车(临时存储,防止页面刷新丢失);
  • 短期免登录(如 “7 天内免登录”,用持久 Cookie 存储令牌);
  • 埋点统计(如记录用户首次访问时间、设备信息)。

不适合用 Cookie 的场景

  • 存储敏感信息(如密码、银行卡号):Cookie 存在本地,易被窃取;
  • 存储大量数据:每个 Cookie 最大 4KB,且每个域名下最多存 50 个左右。

三、Session:服务器端的 “专属账本”—— 属性原理 + 流程

Session 是服务器为每个用户(浏览器)创建的专属存储空间,用于存储敏感 / 复杂信息(如用户权限、订单临时数据)。核心是 “通过 Session ID 关联用户”,我们同样从属性、流程、条件拆解。

1. Session 的核心属性:决定 “存哪里、活多久、怎么关联”

Session 的属性主要围绕 “存储方式” 和 “生命周期”,直接影响网站的性能和扩展性:

属性维度核心选项原理说明适用场景
存储方式内存存储Session 存在 Web 服务器内存(如 Tomcat 内存),读写最快本地开发、小型单机网站
数据库存储(MySQL/PostgreSQL)将 Session ID、数据、过期时间存到数据库表,多服务器共享中小型分布式网站
缓存存储(Redis/Memcached)将 Session 存到内存缓存,支持分布式、自动过期、持久化中大型网站(主流方案)
生命周期超时时间服务器配置 Session 无操作后的过期时间(默认 30 分钟),超时后自动删除控制用户登录状态有效期
主动销毁用户点击 “退出登录”,服务器手动删除 Session安全登出
关联方式Cookie 传递 Session ID(默认)服务器生成 Session ID 后,通过 Cookie 发给浏览器,下次请求携带 ID绝大多数 Web 场景
URL 重写 / 表单隐藏域浏览器禁用 Cookie 时,将 Session ID 拼在 URL 后或藏在表单中特殊隐私场景(极少用)

实战案例:用 Redis 存储 Session(中大型网站主流方案)后端(Spring Boot)配置 Redis 存储 Session,支持分布式:

java

运行

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800, // Session超时时间30分钟redisNamespace = "session:a_com"     // Redis中Session的key前缀
)
public class RedisSessionConfig {// 配置Redis连接@Beanpublic RedisConnectionFactory redisConnectionFactory() {LettuceConnectionFactory factory = new LettuceConnectionFactory();factory.setHostName("localhost");factory.setPort(6379);return factory;}
}

此时 Session 数据会存在 Redis 中,Key 为session:a_com:xxxxxx(xxxxxx 是 Session ID),Value 为序列化后的用户信息(如用户 ID、权限)。

2. Session 的工作流程:5 步实现 “安全记录用户信息”

还是以 “用户登录电商网站” 为例,看 Session 如何配合 Cookie 工作:

  1. 用户首次登录,服务器创建 Session:用户提交登录请求,服务器验证通过后,生成唯一的 Session ID(如3f9d4a7b2c8e),并在 Redis 中创建 Session 对象,存储用户敏感信息(如user_id=123role=VIP);
  2. 服务器传递 Session ID:服务器将 Session ID 通过 Cookie(设为 HttpOnly、Secure)发给浏览器,此时 Cookie 仅存 “ID”,不存实际信息;
  3. 浏览器存储 Session ID:浏览器将包含 Session ID 的 Cookie 存到本地;
  4. 后续请求携带 Session ID:用户下次访问网站(如查看订单),浏览器自动携带 Session ID 的 Cookie,发给服务器;
  5. 服务器查询 Session:服务器解析 Cookie 中的 Session ID,到 Redis 中查询对应的 Session 对象:
    • 若找到 Session 且未过期:通过 Session 中的user_idrole,返回用户的订单数据、VIP 权益;
    • 若未找到 Session(如超时、ID 无效):服务器判定用户未登录,跳转到登录页面;
  6. Session 销毁:用户点击 “退出登录”,服务器删除 Redis 中的 Session 对象,并设置 Cookie 的 Max-Age=0(立即删除浏览器中的 Session ID Cookie)。

3. Session 的使用条件:什么时候该用 Session?

Session 适合存储大量、敏感、临时有效的信息,典型场景:

  • 用户登录后的敏感信息(如用户 ID、权限等级、会员到期时间);
  • 多步骤表单数据(如注册时填了一半的个人信息、下单时的收货地址,临时存在 Session);
  • 临时交互数据(如用户在页面上的筛选条件、分页状态,刷新页面后保持)。

不适合用 Session 的场景

  • 长期存储数据:Session 默认临时有效,超时会删除;
  • 分布式场景下的内存存储:多服务器无法共享内存 Session,用户切换服务器需重新登录(需用 Redis 存储解决)。

四、Cookie 与 Session 的核心逻辑:协同工作 + 关键区别

很多人会把 Cookie 和 Session 搞混,其实它们是 “分工协作” 的关系 ——Cookie 传 “钥匙”(Session ID),Session 存 “内容”(用户信息),核心逻辑是 “通过 Session ID 关联用户状态”。

1. 两者的协同逻辑:为什么需要配合使用?

  • 若只用水 Cookie:敏感信息(如用户权限)存在本地,易被篡改,且 4KB 大小限制无法存复杂数据;
  • 若只用 Session:Session ID 无法传递(浏览器禁用 Cookie 时需特殊处理),且服务器存储压力大;
  • 配合使用:Cookie 仅存 “无意义的 Session ID”(安全),Session 存 “敏感复杂信息”(灵活),既安全又能满足需求。

2. 两者的关键区别:一张表分清

对比维度CookieSession
存储位置浏览器端(用户本地设备)服务器端(内存 / 数据库 / Redis)
存储内容少量文本(≤4KB),仅支持字符串大量复杂数据(无大小限制),支持对象 / 数组
安全性较低(存在本地,易被窃取篡改)较高(核心信息在服务器,仅传 ID)
生命周期可设为临时(关浏览器删)或持久临时(超时 / 退出登录删,默认 30 分钟)
传输开销每次请求 / 响应都携带,增加流量仅传 Session ID,传输开销小
分布式支持天然支持(不依赖服务器)需额外配置(如 Redis 集群)
依赖关系独立工作,不依赖 Session通常依赖 Cookie 传递 ID(可替代)

3. 特殊场景:浏览器禁用 Cookie,Session 还能用吗?

能!Session 的核心是 “Session ID 的传递”,Cookie 只是默认载体,禁用 Cookie 后可换两种方式:

  • URL 重写:将 Session ID 拼在 URL 后(如https://a.com/home?sessionId=3f9d4a7b),服务器从 URL 中获取 ID;缺点:URL 会存在浏览器历史记录,易泄露 ID,且 URL 长度有限制。
  • 表单隐藏域:在表单中加隐藏字段(如<input type="hidden" name="sessionId" value="3f9d4a7b">),提交表单时传递 ID;缺点:仅适用于表单提交,点击普通链接(如 “返回首页”)无法携带 ID。

五、总结:吃透核心,不踩坑

  1. Cookie 是 “浏览器小纸条”:存少量非敏感信息,靠属性保证安全,适合长期存储;
  2. Session 是 “服务器专属账本”:存大量敏感信息,靠 Session ID 关联用户,适合临时存储;
  3. 协同逻辑是关键:Cookie 传 ID,Session 存内容,两者配合实现 Web 状态保持;
  4. 安全属性别漏加:Cookie 的 HttpOnly、Secure、SameSite,Session 的 Redis 存储,是避坑重点。


    学习时间:

    学习时间为学习时间

    学习时间筋肉人
    为学习时间future

    内容为笔记【有时比较抽象,有时比较过于详细,请宽恕。作者可能写的是仅个人笔记,筋肉人future】  


    学习产出:

    • 技术笔记 1遍
    • 有错误请指出,作者会及时改正

    http://www.dtcms.com/a/585453.html

    相关文章:

  • STM32HAL库-F1内部Flash读写操作(官网驱动)
  • 辛集建设网站网络营销推广渠道
  • 外国排版网站企业名录2019企业黄页
  • 微信小程序开发实战:图片转 Base64 全解析
  • 秒杀-订单创建消费者CreateOrderConsumer
  • 单层前馈神经网络的万能逼近定理
  • C# 如何捕获键盘按钮和组合键以及KeyPress/KeyDown/KeyUp事件之间的区别
  • Windows系统不关闭防火墙,允许某个端口的访问怎么设置?
  • UniApp 多个异步开关控制教程
  • 邯郸哪家公司做企业网站比较专业中国制造网是干什么的
  • 做视频网站把视频放在哪里wordpress建站用什么意思
  • ASP.NET Core Web 应用SQLite数据连接显示(1)
  • 网易门户网站建设网站建设及发布的流程
  • 基于python的jlink单片机自动化批量烧录工具
  • 从三路快排到内省排序:探索工业级排序算法的演进
  • CPP 学习笔记 语法总结
  • Qt 跨平台 2048 游戏开发完整教程 (含源码)
  • SortScope 排序算法可视化
  • 组件库引入
  • 手写Spring第25弹:Spring JdbcTemplate深度解析:数据操作如此简单
  • 《Python 小程序编写系列》(第一部):从零开始写一个猜数字游戏
  • 【完整源码+数据集】草莓数据集,yolov8草莓成熟度检测数据集 3207 张,草莓成熟度数据集,目标检测草莓识别算法系统实战教程
  • 英特尔网站开发框架视频教学互动网站建设
  • DeepSeek-OCR实战(01):基础运行环境搭建-RockyLinux
  • 测开学习DAY26
  • VBA经典应用69例应用9:读取工作表中个数不定的数据
  • 网站建设策划书5000字蚂蚁网站建设
  • 【Janet】比较运算符
  • 05 kafka 如何存储较大数据记录
  • 使用Unity ASE插件设置数值不会生效的问题