Web 登录鉴权 (Session, Cookie, Bearer, JWT)
1. 核心问题
Web 登录本质上是在解决一个问题:
服务器怎么知道这次请求是谁发来的?这个人有没有权限?
因为 HTTP 本身是无状态的。
也就是说,服务器默认不会天然记得:
你刚才登录过
你是谁
你有没有权限改个人资料
````
所以每次请求都需要带上某种“凭证”。
常见凭证传递方式有:
Cookie
Authorization: Bearer
X-API-Key:
api-key:
---
## 2. HTTP 是无状态的
比如你先登录:
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
{
"username": "rap",
"password": "123456"
}
然后你再改资料:
POST /api/profile HTTP/1.1
Host: example.com
Content-Type: application/json
{
"nickname": "RapGPT"
}
如果第二个请求里没有任何凭证,服务器不知道你是谁。
所以登录成功后,服务器会给你某种凭证。之后你每次请求都带上它。
---
## 3. Cookie + Session 模式
这是传统网站最常见的模式。
### 登录流程
用户登录:
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
{
"username": "rap",
"password": "123456"
}
服务器验证成功后:
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; HttpOnly; Secure
Content-Type: application/json
{
"message": "login success"
}
浏览器保存这个 cookie。
之后请求改资料时,浏览器会自动带上:
POST /api/profile HTTP/1.1
Host: example.com
Cookie: session_id=abc123
Content-Type: application/json
{
"nickname": "RapGPT"
}
服务器看到:
session_id=abc123
然后去服务端 session 存储里查:
abc123 → user_id=42
于是服务器知道:
这个请求来自 user_id=42
---
## 4. Session 是什么?
Session 可以理解成服务器保存的一份登录状态。
例如服务端保存:
session_id: abc123
user_id: 42
role: user
expires_at: 2026-05-09 12:00:00
浏览器这边只保存一个 `session_id`。
所以 Cookie + Session 的核心是:
浏览器保存 session_id
服务器保存真正的登录状态
---
## 5. 关掉窗口 session 会不会没?
不一定。
这取决于 cookie 的过期策略。
### Session Cookie
如果 cookie 没有设置明确过期时间,通常属于 session cookie。
表现大概是:
关闭浏览器后可能失效
但现代浏览器有恢复会话机制,所以不一定是关一个窗口或标签页就立刻失效。
### Persistent Cookie
如果服务器设置了过期时间:
Set-Cookie: session_id=abc123; Max-Age=604800; HttpOnly; Secure
那这个 cookie 可以保存 7 天。
这就是很多网站“保持登录”“记住我”的原理。
> 过期之外还有一个独立维度是**作用域**:不设 `Domain` 的 cookie 只作用于当前主机,多个子域必须各自登录一次。见 [跨子域会话共享 (Cross-Subdomain Session Sharing)](/index.php/archives/764/)。
---
## 6. Bearer Token 模式
API、移动 App、前后端分离项目、第三方服务更常见 Bearer token。
请求长这样:
POST /api/profile HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
{
"nickname": "RapGPT"
}
核心 header 是:
Authorization: Bearer
可以理解成:
我拿着一张通行证。
谁持有这个 token,谁就被认为有权限。
Bearer 的字面意思就是“持有者”。
---
## 7. Bearer 不等于 JWT
需要分清楚:
Bearer = token 的携带方式
JWT = token 的一种格式
Bearer 后面可以是 JWT:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
也可以是普通随机字符串:
Authorization: Bearer abc123randomtoken
也可以是 API key:
Authorization: Bearer sk-xxxx
所以:
Bearer token 不一定是 JWT
JWT 也不一定必须放在 Bearer 里
但现实中最常见组合是:
Authorization: Bearer
---
## 8. JWT 是什么?
JWT = JSON Web Token。
它通常长这样:
xxxxx.yyyyy.zzzzz
三段分别是:
header.payload.signature
payload 里可能有:
{
"user_id": 42,
"role": "user",
"exp": 1770000000
}
服务器可以验证:
这个 token 是不是我签发的?
有没有被篡改?
有没有过期?
这个用户有没有权限?
---
## 9. Stateful 和 Stateless
这是另一个维度。
### Stateful Session
服务器保存登录状态。
session_id=abc123 → user_id=42
每次请求带 cookie,服务器查 session。
特点:
状态在服务器
服务端可以随时删除 session
适合传统网站
---
### Stateless Token
服务器不保存 session 表。
token 自己带用户信息和过期时间,比如 JWT。
服务器每次只验证:
签名是否正确
是否过期
权限是否足够
特点:
服务端不需要保存会话状态
适合 API、App、分布式系统
但 token 泄露后,在过期前可能被滥用
---
## 10. Cookie、Bearer、Session、JWT 不是同一维度
不要简单理解成:
Cookie = Session
Bearer = JWT
更准确是:
Cookie 是一种传凭证的方式
Bearer 也是一种传凭证的方式
Session 是一种服务器保存登录状态的机制
JWT 是一种 token 格式
Stateless 是一种服务器不保存会话状态的设计
它们可以组合。
例如:
### Cookie + Session
Cookie: session_id=abc123
服务器查:
abc123 → user_id=42
### Bearer + JWT
Authorization: Bearer eyJhbGciOi...
服务器验证 JWT 签名。
### Cookie + JWT
Cookie: access_token=eyJhbGciOi...
token 是 JWT,但传输方式是 Cookie。
### Bearer + Stateful Token
Authorization: Bearer random_token_abc123
服务器拿随机 token 去数据库查用户。
---
## 11. API Key 和 Bearer
像 OpenAI API 这种常见写法:
Authorization: Bearer sk-xxxx
这里 Bearer 后面不是 JWT,而是 API key。
它更像机器对机器的鉴权:
你的程序每次请求都带 API key
服务器根据 key 判断账号、项目、权限、额度、限流
---
## 12. X-API-Key
有些服务不用 Bearer,而是用:
X-API-Key: your_api_key
或者:
api-key: your_api_key
这是另一种常见的自定义 header 鉴权方式。
对比:
Authorization: Bearer xxx 更标准
X-API-Key: xxx 很常见,简单直接
api-key: xxx 一些云厂商或企业网关常用
具体用哪种,看服务端文档。
---
## 13. 安全注意事项
Bearer token / API key / session_id 都属于敏感凭证。
不要:
不要提交到 GitHub
不要打印到日志
不要放进 URL query
不要发给别人
不要写死在前端代码里
尤其是 Bearer token,因为它的逻辑是:
谁持有 token,谁就有权限
所以泄露后,别人可以冒充你,直到 token 过期或被吊销。
---
## 14. 总结
最重要的心智模型:
HTTP 本身无状态。
登录后,客户端必须在后续请求里带某种凭证。
服务器根据凭证判断你是谁、有没有权限。
传统网站常见:
Cookie + Session
API / App / 前后端分离常见:
Authorization: Bearer
第三方 API 也常见:
X-API-Key:
最终要分清四个概念:
Cookie:浏览器自动携带的凭证传输方式
Session:服务器保存的登录状态
Bearer:Authorization 头里的 token 携带方式
JWT:一种带签名的 token 格式
---