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

HTTP 完全指南(三):Cookie、Session 与 Token 深度详解

引言

上一篇我们讲了 HTTP 缓存。今天要解决的是 HTTP 最著名的缺陷:无状态

什么叫无状态?服务器每次收到请求,都把它当成一个全新的请求,完全不记得刚才这个客户端来过没有、做过什么。你登录了淘宝,刷新一下页面,服务器问:"你是谁?请重新登录"——这就是无状态带来的问题。

为了让 HTTP "记住"用户,诞生了三套方案:CookieSessionToken。它们各自有不同的工作原理和适用场景,本文将逐一深挖。

第一部分:Cookie

一、Cookie 是什么

Cookie 是服务器让浏览器保存在本地的一小段数据(通常不超过 4KB)。浏览器每次请求该服务器时,会自动带上所有 Cookie

二、Cookie 的属性

Set-Cookie: session_id=abc123; Domain=.example.com; Path=/; Max-Age=3600; HttpOnly; Secure; SameSite=Lax
属性含义示例
Name=ValueCookie 的名字和值session_id=abc123
Domain允许访问的域名范围.example.com(所有子域名都能访问)
Path允许访问的路径范围/(整个网站);/admin(只管理后台)
Max-Age存活秒数(相对时间)3600(1小时后过期)
Expires过期时间(绝对时间)Mon, 02 Jun 2025 10:00:00 GMT
HttpOnly禁止 JavaScript 访问只通过 HTTP 传输,document.cookie读不到
Secure只在 HTTPS 连接中传输HTTP 明文不传输此 Cookie
SameSite跨站请求控制Strict/Lax/None

三、HttpOnly 和 Secure 为什么重要

四、SameSite 详解

第二部分:Session

一、Session 是什么

Session 是存储在服务器端的用户数据。浏览器只保存一个session_id(通常存在 Cookie 中),服务器根据这个 ID 找到对应的 Session 数据。

二、Session 的存储位置

方式优点缺点
内存最快重启丢失,不能多服务器共享
文件重启不丢慢,不能多服务器共享
Redis快 + 持久 + 多服务器共享需要额外部署
数据库持久可靠最慢

三、Cookie vs Session

对比CookieSession
存储位置浏览器端服务器端
安全性较低(客户端可见)较高(服务器控制)
容量约 4KB无限制
网络开销每次请求自动带上只有一个 session_id
服务器压力需要存储和管理
适用场景记住用户偏好、主题登录状态、敏感数据

第三部分:Token(JWT)

一、Token 是什么

Token 是一段自包含的加密字符串,服务器签发后交给客户端,客户端每次请求手动携带这个 Token。

最流行的 Token 实现是JWT(JSON Web Token)。

二、JWT 的结构

JWT 由三部分组成,用.分隔:

三、JWT 的验证过程

四、Token vs Session

对比SessionJWT Token
存储位置服务器端客户端
服务器状态有状态(需要存 Session)无状态(Token 自包含)
扩展性多服务器需要共享 Session(Redis)天然支持分布式
注销删除服务器 Session 即可需要额外机制(黑名单)
安全性Session ID 泄露可冒充Token 泄露也可冒充
数据量Cookie 只传 ID,很小Token 较大(每次都要传)

第四部分:JWT 实战

一、服务端签发 JWT(C 语言伪代码)

// JWT 结构(简化) typedef struct { char header[128]; // Base64 编码的 Header char payload[512]; // Base64 编码的 Payload char signature[256]; // 签名 } JWT; // 签发 JWT char* createToken(int userId, const char* username, const char* secret) { // 1. 构造 Header const char* header = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}"; char* header_b64 = base64_encode(header); // 2. 构造 Payload char payload[512]; time_t now = time(NULL); sprintf(payload, "{\"userId\":%d,\"username\":\"%s\",\"iat\":%ld,\"exp\":%ld}", userId, username, now, now + 3600); // 1 小时过期 char* payload_b64 = base64_encode(payload); // 3. 计算签名 char to_sign[1024]; sprintf(to_sign, "%s.%s", header_b64, payload_b64); char* signature = hmac_sha256(to_sign, secret); char* signature_b64 = base64_encode(signature); // 4. 拼接完整 Token char* token = malloc(2048); sprintf(token, "%s.%s.%s", header_b64, payload_b64, signature_b64); return token; }

二、前端使用 JWT

// 登录成功后存储 Token fetch('/api/login', { method: 'POST', body: JSON.stringify({ username: 'zhangsan', password: '123' }) }) .then(res => res.json()) .then(data => { localStorage.setItem('token', data.token); // 存到本地 }); // 后续请求带上 Token fetch('/api/profile', { headers: { 'Authorization': 'Bearer ' + localStorage.getItem('token') } });

三、Access Token + Refresh Token

第五部分:三种方案对比与选择

对比CookieSessionJWT Token
谁保存浏览器服务器浏览器
谁验证服务器服务器服务器(密钥验证)
自动携带✅ 浏览器自动✅ Cookie 带 ID❌ 代码手动加
跨域受限(Domain)受限天然支持
移动端不方便不方便友好
分布式不方便需要 Redis天然支持
注销删 Cookie删 Session需要额外处理
防 CSRF需 SameSite需 SameSite不受 CSRF 影响

选择建议

场景推荐
传统 Web 网站(前后端不分离)Session + Cookie
RESTful APIJWT Token
移动 AppJWT Token
微服务/分布式系统JWT Token
需要立即注销Session(或 Token + 黑名单)

第六部分:常见攻击与防范

第七部分:面试题

1. Q:Cookie、Session、Token 的区别?

A:Cookie 存储在浏览器端,浏览器自动携带;Session 存储在服务器端,Cookie 只存 session_id;Token 也存储在浏览器端,但代码手动携带。Session 适合传统 Web,Token 适合 API 和分布式系统。

2. Q:JWT 的 Payload 是加密的吗?

A:不是!只是 Base64 编码,任何人都能解码。不要放密码等敏感信息。JWT 的防篡改靠的是 Signature 签名。

3. Q:Token 过期了怎么办?

A:用 Refresh Token 换取新的 Access Token。两个 Token 都过期才需要重新登录。

4. Q:Cookie 的 HttpOnly 和 Secure 有什么作用?

A:HttpOnly 禁止 JavaScript 读取 Cookie(防 XSS 窃取);Secure 要求 Cookie 只在 HTTPS 中传输(防中间人窃取)。

5. Q:CSRF 攻击是什么?怎么防?

A:攻击者诱导用户点击链接,利用用户已登录的身份发起恶意请求。防御方式:SameSite Cookie、CSRF Token、验证 Referer。JWT 方案天然不受 CSRF 影响(Token 不是浏览器自动携带的)。


总结

一、三种方案对比

方案核心原理最适合
Cookie浏览器自动存储和携带的小数据记住偏好、跟踪
Session服务器存储状态,Cookie 只传 ID传统 Web 登录
JWT Token自包含加密令牌,客户端主动携带API、移动端、分布式

二、一句话记忆

Cookie 存浏览器、自动带,Session 存服务器、Cookie 只带 ID,Token 自包含、手动带。Session 适合传统网站,Token 适合 API 和分布式。JWT 的 Payload 只编码不加密,防篡改靠签名。

http://www.jsqmd.com/news/965467/

相关文章:

  • 告别APN,5G时代DNN配置实战:手把手教你用UDM脚本完成用户签约与切片绑定
  • 3分钟为Windows 11 LTSC找回微软商店:告别繁琐安装,拥抱现代应用生态
  • 从YOLOv5到ViT:聊聊CBAM注意力机制在CV任务中的“万金油”用法
  • CSDN AI内容分发究竟如何“读懂”微信/知乎/小红书?:深度拆解其跨平台排版引擎的5层自适应架构
  • 短视频矩阵混剪工具厂商又洗牌?短视频矩阵头部厂商集体押注AI Agent自动云混剪
  • 别再只跑线性回归了!用R的lme4包搞定GLMM(广义线性混合模型),处理非正态与相关数据实战
  • 8款主流网盘直链下载工具终极指南:免费获取真实下载链接的简单方法
  • 别再死记硬背寄存器了!用C2000Ware库函数搞定TMS320F280049C ADC配置(附代码)
  • SAP ABAP ALV显示优化:手把手教你用自定义例程搞定小数位显示与隐藏
  • 原来,搞Agent的攻城狮们,每天都在折腾这些……看看你正在经历哪个?
  • 拆解BCM5396:这颗16口千兆交换芯片,在工业网关里到底怎么用?
  • 从阶乘到积分:用Python和SymPy可视化Gamma函数,理解欧拉的数学直觉
  • 告别手动写Cron!用Vue-cron组件5分钟搞定可视化定时任务配置
  • 影刀RPA教程:从零开发拼多多店群全自动运营软件,我把繁琐切号流程彻底干掉了(附系统架构)
  • 别再手动打字了!用Chrome的Web Speech API做个语音输入助手(附完整代码)
  • 2026年近期邢台电动车长租专业服务商盘点:业内直销公司推荐 - 2026年企业资讯
  • 从ResNet到Vision Transformer:深入理解nn.AdaptiveAvgPool2d在经典网络中的关键作用
  • 5G物联网卡开户避坑指南:从DNN、切片到QoS模板的完整配置流程
  • 揭秘Melodyne的‘黑科技’:它的音频分析算法到底比手动修音强在哪?
  • 别再死记硬背公式了!用Python仿真带你直观理解缝隙天线辐射原理
  • 2026年Q2晚樱樱花树苗专业供应商实测评测:临沂樱花树苗/临沂海棠树苗/临沂白蜡树苗/临沂石榴树苗/垂丝海棠树苗/选择指南 - 优质品牌商家
  • P4实战:在Mininet里用Python给BMv2交换机下发路由表(含完整代码)
  • 从PXE安装到VNC登录:图解FusionSphere OpenStack网络流量到底怎么走的?
  • 别再被‘Your branch is ahead’吓到了!Git新手必看的本地与远程同步保姆级指南
  • 构建你的 Agent 工具库:规范、命名与版本管理
  • 定制辊压成型模具技术要点与可靠选型逻辑解析:轻钢龙骨辊压设备/金属板材辊压设备/钢结构冷弯成型设备/门框冷弯辊压设备/选择指南 - 优质品牌商家
  • 告别数据混乱!用CDO 1.9.10高效处理气象NetCDF/GRIB数据的保姆级教程
  • Python基础:复数类型complex应用场景详解
  • 别再只会用串口读温度了!手把手教你用STM32的ADC解析PT100模块的模拟信号(附完整代码)
  • 2026年国内白蜡树苗供应商综合实力排行:晚樱樱花树苗、染井吉野樱花树苗、红宝石海棠树苗、绚丽海棠树苗、西府海棠树苗选择指南 - 优质品牌商家