第三章 身份认证机制:、OAuth 2.0、JWT、多因素认证的选型与安全实践
说到接口安全,身份认证是第一道门。不少团队上来就选 JWT,觉得“流行就靠谱”。其实不然。我见过太多项目因为选型不当,搞出一堆安全漏洞。今天就跟你聊聊这四种认证方式的真实面目,以及我踩过的坑。
:简单但别裸奔
是最直接的认证方式——客户端发请求时带一个秘钥。很多开放平台(比如一些天气 API)仍然在用。
- Key 必须通过 HTTPS 传输,明文传输等于送密码
- 定期轮换,最少每季度一次
- 绑定来源 IP 或 User-Agent,缩小滥用范围
我在审计一个内部日志系统时发现,他们把 直接写在前端 JS 里,任何人都能从浏览器 DevTools 里扒出来。那之后我强制要求: 绝不能出现在客户端代码中。后端发、后端存,才是正确姿势。
OAuth 2.0:授权框架,不是认证协议
很多人把 OAuth 2.0 当成“登录方案”,但它本质上是一个授权框架。它的四个流程(授权码、隐式、密码、客户端凭证)各有使用场景。
| 流程类型 | 适用场景 | 安全风险 |
|---|---|---|
| 授权码 | Web应用、移动端 | 需绑定 PKCE 防拦截 |
| 隐式 | 纯前端 SPA(已不推荐) | access_ 直接暴露在 URL 片段 |
| 密码 | 高度信任的第一方应用 | 明文密码在后端流转 |
| 客户端凭证 | 服务到服务调用 | client_secret 泄露风险 |
我个人习惯:能授权码就别用密码,能用 PKCE 就别裸授权码。特别是移动端,一定要带上 PKCE,防止授权码被中间人截获。
JWT:无状态,但别放敏感数据
JWT 核心优势是无状态——服务端不需要存储会话。但很多人忽略了一个问题:Header + Payload 只是 Base64 编码,不是加密。谁都能解码看到 Payload 内容。
// 不推荐:放敏感信息
{
"sub": "user_123",
"role": "admin",
"credit_card": "4111-1111-1111-1111"
}
// 推荐:只放必要信息
{
"sub": "user_123",
"role": "admin",
"iat": 1700000000,
"exp": 1700003600
}
我曾经审计过一个电商平台,他们把用户手机号、身份证号都塞进 JWT 里方便“快速查询”。结果有个第三方库解析出全部明文。嗯,那之后我制定了一条铁律:JWT 只放标识,不放数据。需要用户信息?走接口查询。
- 优先用 RS256(非对称),避免 HS256 密钥泄露
- 设置合理的 exp,建议 15-30 分钟
- 验证算法白名单——防止 alg=none 攻击
- 加 jti(唯一标识),用于检测重放
多因素认证:最后一道防线
不管是 、OAuth 还是 JWT,只要单因素被攻破,整个系统就完了。多因素认证(MFA)就是给认证加第二把锁。
常见第二因素包括:TOTP(时间型一次性密码)、SMS 验证码、硬件密钥(如 YubiKey)、生物特征。
- TOTP:离线可用,安全度高,但用户配置稍麻烦
- SMS:简单但易受 SIM 劫持,我强烈不推荐做主要方案
- 硬件密钥:最安全,但成本高,适合管理员和高风险操作
我在一个金融项目里推行了“管理员必须用硬件密钥 + 口令”的双因素。起初业务方觉得麻烦,直到有一次撞库攻击被 MFA 拦住,他们才服气:这 30 秒的验证能省下后续数小时的应急响应。
选型决策:一张图理清思路
下面这张 SVG 图概括了我平时做认证选型的决策路径。你可以把它贴在团队墙上。
避坑指南
- 别硬编码到代码仓库。我记得有个团队把 Key 写到 GitHub 公开仓库的配置文件中,被爬虫抓了个精光。一定要用环境变量或密钥管理服务。
- OAuth 授权回调地址必须严格校验。我曾经碰到一个系统,回调地址只检查子串(比如“example.com”可以绕过为“evil.com/example.com”),结果是攻击者拿到了合法授权码。
- JWT 过期时间别设太长。有些项目为了方便把 JWT 设成 7 天,泄漏后攻击者能长期冒用。15-30 分钟是主流做法,配合 refresh 实现无感刷新。
- MFA 恢复码必须安全保管。用户丢失设备时,恢复码是最后救命稻草。但很多平台把恢复码用明文邮件发出——这等于给了攻击者后门。
嗯,以上就是我对这四种认证机制核心安全实践的理解。没有银弹,只有选型匹配场景、实现不偷懒,才能把风险降到最低。