认证方式对比 #
Bearer Token 认证 #
OAuth 2.0 标准的一部分(RFC 6750),基于令牌的 HTTP 认证方案。
Authorization: Bearer <token>
Cookie 认证 #
基于浏览器 Cookie 机制的传统认证方式。
Set-Cookie: sessionId=abc123; HttpOnly; Secure
核心差异 #
| 特性 | Cookie | Bearer Token |
|---|---|---|
| 存储位置 | 浏览器自动管理 | 客户端手动存储(localStorage/内存) |
| 发送方式 | 浏览器自动带上 | 手动添加到请求头 |
| 服务器状态 | 需要 Session 存储 | 无状态,token 自包含 |
| 跨域 | 受同源策略限制 | 不受限制 |
| CSRF 攻击 | 易受攻击 | 免疫 |
状态管理差异 #
Cookie/Session(有状态) #
# 服务器必须存储 session
sessions = {
"abc123": {
"user_id": 1001,
"username": "user",
"permissions": ["read", "write"]
}
}
# 每次请求都要查询
session_id = cookie.get("sessionId")
user_data = sessions.get(session_id) # 查询数据库/Redis
JWT Token(无状态) #
# Token 自包含所有信息
{
"user_id": 1001,
"username": "user",
"permissions": ["read", "write"],
"exp": 1704100000
}
# 服务器只需验证签名
payload = jwt.verify(token, secret_key)
CSRF 攻击原理 #
Cookie 易受攻击 #
浏览器自动发送 Cookie,不管请求从哪里发起:
<!-- 恶意网站 evil.com -->
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="amount" value="10000">
</form>
<!-- 提交时自动带上 bank.com 的 Cookie -->
Token 免疫原因 #
Token 必须手动添加,攻击者无法控制:
// 正常请求需要手动添加
fetch('https://api.com/transfer', {
headers: {
'Authorization': 'Bearer ' + token // 必须手动添加
}
})
// 恶意网站无法读取 localStorage(同源策略)
// 也无法自动添加 Authorization 头
混合方案 #
可以把 JWT 存在 Cookie 中,结合两者优势:
// 设置 Cookie
res.cookie('jwt', token, {
httpOnly: true, // 防 XSS
secure: true, // 仅 HTTPS
sameSite: 'strict' // 防 CSRF
})
适用场景 #
- Web 应用:Cookie + JWT
- 移动 APP:Bearer Token(无 Cookie 机制)
- API 调用:Bearer Token(更灵活)
- 跨域请求:Bearer Token(Cookie 受限)
本质区别 #
- Cookie:浏览器自动行为,方便但控制权有限
- Token:开发者手动控制,麻烦但安全可控
Cookie vs Bearer 是传输方式的区别,Session vs JWT 才是认证机制的区别。