HTTP/HTTPS 与 Cookie 深入解析:Web 通信的安全基石

每次你在浏览器输入网址、点击登录、浏览商品时,背后都有一套精密的通信机制在运作。HTTP 负责传输数据,HTTPS 保证数据安全,Cookie 则帮你”记住身份”。本文将深入解析这三者的原理与协作方式。


一、HTTP 基础

1.1 什么是 HTTP

HTTP(HyperText Transfer Protocol,超文本传输协议)是浏览器与服务器之间的通信语言。可以把 HTTP 想象成明信片——内容任何人都能看到,没有加密。

1
2
3
4
5
6
客户端(浏览器)                         服务器
| |
| --- 请求(Request)------------> |
| |
| <--- 响应(Response)----------- |
| |

HTTP 的特点:

  • 无状态:每次请求都是独立的,服务器不记得上一次请求
  • 基于请求-响应模型:客户端发起请求,服务器返回响应
  • 灵活可扩展:通过 Header 可以传输任意类型的数据

1.2 请求方法

方法 用途 是否幂等 请求体 典型场景
GET 获取资源 查看文章列表
POST 创建资源 提交表单、登录
PUT 更新资源(全量) 修改用户信息
DELETE 删除资源 删除一篇文章
PATCH 更新资源(部分) 修改密码
OPTIONS 查询支持的方法 CORS 预检请求

1.3 状态码

1
2
3
4
5
1xx  信息性     请求已接收,继续处理
2xx 成功 请求已成功处理
3xx 重定向 需要进一步操作
4xx 客户端错误 请求有误
5xx 服务器错误 服务器处理失败

常见状态码详解:

状态码 含义 说明
200 OK 成功 请求正常返回
201 Created 已创建 POST 成功创建资源
301 Moved Permanently 永久重定向 URL 已永久更改(SEO 友好)
302 Found 临时重定向 临时跳转
304 Not Modified 未修改 使用缓存
400 Bad Request 请求错误 参数有误
401 Unauthorized 未认证 需要登录
403 Forbidden 禁止访问 权限不足
404 Not Found 未找到 资源不存在
500 Internal Server Error 服务器错误 服务端异常
502 Bad Gateway 网关错误 上游服务异常
503 Service Unavailable 服务不可用 服务过载或维护

1.4 请求头与响应头

关键请求头:

1
2
3
4
5
6
7
8
Host: example.com              # 目标主机
User-Agent: Mozilla/5.0 # 客户端类型
Accept: text/html # 接受的响应格式
Accept-Language: zh-CN # 偏好语言
Accept-Encoding: gzip # 支持的压缩格式
Cookie: session=abc123 # 携带的 Cookie
Content-Type: application/json # 请求体格式
Authorization: Bearer token # 认证令牌

关键响应头:

1
2
3
4
5
6
Content-Type: text/html        # 响应体格式
Content-Length: 1234 # 响应体大小
Set-Cookie: session=abc123 # 设置 Cookie
Cache-Control: max-age=3600 # 缓存策略
Location: /new-url # 重定向目标
Access-Control-Allow-Origin: * # CORS 跨域允许

二、HTTPS 原理

2.1 为什么需要 HTTPS

HTTP 的问题在于明文传输,存在三大风险:

风险 说明 示例
窃听 第三方可读取传输内容 公共 WiFi 下账号被盗
篡改 第三方可修改传输内容 运营商插入广告
伪造 无法验证服务器身份 钓鱼网站冒充银行

HTTPS = HTTP + TLS/SSL,可以理解为加密信封——内容被加密,只有收件人能看。

2.2 对称加密 vs 非对称加密

特性 对称加密 非对称加密
密钥 加密和解密用同一把密钥 公钥加密,私钥解密
速度 快(适合大量数据) 慢(约慢 1000 倍)
密钥分发 困难(如何安全传递密钥?) 容易(公钥可以公开)
典型算法 AES、DES、ChaCha20 RSA、ECC、Ed25519
类比 保险箱 + 同一把钥匙 邮箱投递口(公钥)+ 钥匙(私钥)

HTTPS 的巧妙之处:结合两者优点——用非对称加密交换密钥,再用对称加密传输数据。

2.3 TLS 握手过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
客户端                                          服务器
| |
| --- 1. ClientHello ----------------------> |
| 支持的 TLS 版本、加密套件、随机数 |
| |
| <--- 2. ServerHello ---------------------- |
| 选定的加密套件、随机数、证书 |
| |
| --- 3. 验证证书 --------------------------> |
| 验证证书是否由可信 CA 签发 |
| |
| --- 4. Key Exchange ----------------------> |
| 用服务器公钥加密的预主密钥 |
| |
| <--- 5. Finished ------------------------- |
| 双方根据三个随机数生成会话密钥 |
| |
| <=== 6. 加密通信开始 ====================> |
| 所有数据用会话密钥加密传输 |

关键点:

  • 三个随机数:客户端随机数 + 服务器随机数 + 预主密钥 = 会话密钥
  • 前向保密:即使服务器私钥泄露,历史通信也无法被解密(因为每次握手生成新密钥)

2.4 证书验证

数字证书由 CA(Certificate Authority,证书颁发机构)签发,包含:

1
2
3
4
5
6
7
证书内容:
- 域名(example.com)
- 公钥
- 颁发者(如 Let's Encrypt)
- 有效期
- 证书指纹(SHA-256)
- 数字签名(CA 的私钥签名)

浏览器验证流程:

  1. 检查证书是否在有效期内
  2. 检查证书域名是否匹配
  3. 检查证书链是否由可信 CA 签发
  4. 检查证书是否已被吊销(CRL/OCSP)

2.5 性能开销与优化

HTTPS 的额外开销主要在 TLS 握手阶段:

优化手段 效果
TLS 1.3 握手从 2-RTT 降至 1-RTT
Session Resume 复用之前的会话,跳过完整握手
OCSP Stapling 服务器预取证书状态,减少客户端查询
HTTP/2 基于 HTTPS,多路复用提升性能
CDN 边缘节点终止 TLS,减少延迟

三、Cookie 详解

Cookie 是服务器发送到浏览器并保存的一小段数据。可以把 Cookie 想象成身份证会员卡——浏览器每次请求时自动携带,让服务器”认出你”。

为什么需要 Cookie?因为 HTTP 是无状态的——服务器不记得你。Cookie 帮服务器建立”记忆”。

3.2 工作流程

1
2
3
4
5
6
7
8
9
10
11
12
13
客户端                                         服务器
| |
| --- 1. 登录请求 -------------------------> |
| POST /login {user, password} |
| |
| <--- 2. 响应 + Set-Cookie ---------------- |
| Set-Cookie: session=abc123; HttpOnly |
| |
| --- 3. 后续请求 --------------------------> |
| Cookie: session=abc123 |
| |
| <--- 4. 服务器识别身份 ------------------- |
| 根据 session=abc123 查找用户信息 |
属性 说明 示例
Name Cookie 名称 session_id
Value Cookie 值 abc123xyz
Domain 适用的域名 .example.com(包含子域)
Path 适用的路径 /api(仅 /api 下的请求携带)
Expires 过期时间 Thu, 01 Dec 2026 16:00:00 GMT
Max-Age 有效期(秒) 86400(24 小时)
HttpOnly 禁止 JS 访问 true(防 XSS 窃取)
Secure 仅 HTTPS 传输 true
SameSite 跨站限制 Strict / Lax / None

SameSite 详解:

行为 适用场景
Strict 跨站完全不发送 Cookie 银行、支付等高安全场景
Lax 顶级导航(GET)允许发送 大多数场景的默认值
None 始终发送(需配合 Secure) 第三方 Cookie(如嵌入内容)
特性 Cookie + Session Token(如 JWT)
存储位置 服务端存 Session,客户端存 Cookie 客户端存 Token
服务器压力 每个 Session 占用服务器内存 无状态,无需存储
扩展性 多服务器需共享 Session 天然支持分布式
跨域支持 受 Cookie 同源策略限制 更灵活
安全性 HttpOnly 防 XSS 需防 Token 泄露
典型场景 传统 Web 应用 前后端分离、移动端

选择建议:

  • 传统服务端渲染项目 → Cookie + Session
  • 前后端分离 / 移动端 → Token(JWT)
  • 需要撤销机制 → Cookie + Session 或短有效期 Token + Refresh Token

1. 防止 XSS 攻击窃取 Cookie

1
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
  • HttpOnly:JavaScript 无法通过 document.cookie 访问
  • Secure:只在 HTTPS 下传输
  • SameSite=Lax:限制跨站请求携带

2. 防止 CSRF 攻击

1
2
3
SameSite=Strict    → 完全禁止跨站携带(最安全,但用户从外部链接点击进来不会带 Cookie)
SameSite=Lax → 允许顶级导航 GET 请求携带(推荐)
CSRF Token → 表单中嵌入随机 Token,服务器验证

3. Cookie 大小与数量限制

限制项 典型值
单个 Cookie 大小 4KB
每个域名 Cookie 数量 50-150 个(浏览器不同)
总 Cookie 大小 4MB 左右

超出限制时的替代方案:

  • localStorage:5MB,不过期,但不随请求自动发送
  • sessionStorage:同 localStorage,但标签页关闭即清除
  • IndexedDB:大量结构化数据存储

四、实战配置

4.1 Nginx 配置 HTTPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 443 ssl http2;
server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

# TLS 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;

# HSTS(强制浏览器使用 HTTPS)
add_header Strict-Transport-Security "max-age=63072000" always;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
}

# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
1
2
3
4
5
6
7
8
9
// 设置 Cookie
document.cookie = "theme=dark; path=/; max-age=86400; SameSite=Lax";

// 读取所有 Cookie
const cookies = document.cookie;
console.log(cookies); // "theme=dark; session=abc123"

// 删除 Cookie(设置过期时间为过去)
document.cookie = "theme=; path=/; max-age=0";
1
2
3
4
5
6
7
8
9
10
11
# 登录成功后设置 Session Cookie
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123def456; Path=/; HttpOnly; Secure; SameSite=Lax

# 记住我功能(持久 Cookie)
HTTP/1.1 200 OK
Set-Cookie: remember_token=xyz789; Path=/; Max-Age=2592000; HttpOnly; Secure

# 清除 Cookie
HTTP/1.1 200 OK
Set-Cookie: session_id=; Path=/; Max-Age=0

五、常见问题与最佳实践

当前后端分离时,前端 localhost:3000 请求后端 api.example.com,Cookie 默认不会发送。

解决方案:

1
2
3
4
5
6
// 前端请求配置(Axios)
axios.defaults.withCredentials = true;

// 后端 CORS 配置
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Credentials: true

注意:Access-Control-Allow-Origin 不能设为 *,必须指定具体域名。

5.2 SameSite 与 CSRF 防护

1
2
3
4
5
场景:用户在 bank.com 已登录,访问恶意网站 evil.com

SameSite=None → evil.com 的请求会携带 bank.com 的 Cookie → CSRF 攻击
SameSite=Lax → evil.com 的 POST 请求不携带 Cookie → 防住大部分 CSRF
SameSite=Strict → 从 evil.com 点击链接到 bank.com 也不携带 → 最安全但体验差

5.3 HTTPS 混合内容

页面通过 HTTPS 加载,但其中引用了 HTTP 资源(图片、脚本等),浏览器会阻止或警告。

1
2
3
4
5
6
7
<!-- 错误:混合内容 -->
<script src="http://example.com/lib.js"></script>
<img src="http://example.com/photo.jpg">

<!-- 正确:使用相对协议或 HTTPS -->
<script src="//example.com/lib.js"></script>
<img src="https://example.com/photo.jpg">

总结

HTTP 是 Web 通信的基础语言,HTTPS 在其上加了一层加密保护,Cookie 则解决了 HTTP 无状态的问题。三者共同构成了现代 Web 应用的通信基石。

核心要点:

  • HTTP:明文传输,无状态,请求-响应模型
  • HTTPS:TLS 握手交换密钥,对称加密传输数据,证书验证身份
  • Cookie:通过 HttpOnly + Secure + SameSite 三重防护保障安全
  • Session vs Token:传统项目用 Session,前后端分离用 JWT

在实际项目中,始终使用 HTTPS,合理配置 Cookie 安全属性,根据架构选择合适的会话管理方案。

🔥 0 打卡天