3、身份认证机制:OAuth2.0流程、JWT令牌、Session与Token对比
身份认证这块,说实话是消费者数据访问里最容易出幺蛾子的环节。我见过太多项目,接口写得漂漂亮亮,结果认证一塌糊涂,数据直接裸奔。今天咱们就把OAuth2.0、JWT、Session和Token这几个东西彻底捋清楚。
3.1 OAuth2.0:别自己造轮子
OAuth2.0说白了就是一个授权协议。它解决的核心问题是:让第三方应用能够有限度地访问用户资源,而不需要知道用户的密码。
我刚开始接触时也觉得绕,后来发现记住四个角色就行:
- 资源所有者——就是用户本人
- 客户端——想访问数据的那个App
- 授权服务器——负责发令牌的
- 资源服务器——存着用户数据的地方
举个实际例子。你打开一个第三方记账软件,想让它读取你的银行流水。这时候:
- 记账软件(客户端)把你引导到银行登录页
- 你输入账号密码,银行问你「是否允许记账软件读取流水?」
- 你点了同意,银行给记账软件一个授权码
- 记账软件拿着授权码去找银行换令牌
- 之后记账软件每次请求数据,都带着这个令牌
你看,你的密码从来没给过记账软件。这就是OAuth2.0的精髓。
核心流程(授权码模式):
用户 → 客户端 → 授权服务器(登录+授权)
↓
授权码 → 客户端 → 授权服务器(换令牌)
↓
访问令牌 → 客户端 → 资源服务器(拿数据)
我个人习惯用授权码模式,安全系数最高。曾经有个项目图省事用了隐式模式,结果令牌直接暴露在URL里,被运维抓了个正着……嗯,从那以后我再也不敢偷懒了。
3.2 JWT令牌:轻量但别乱用
JWT(JSON Web Token)现在太火了。它本质上就是一个自包含的令牌,三段式结构:Header.Payload.Signature。
我拆开给你看:
// 一个典型的JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
解码后长这样:
| 部分 | 内容 | 说明 |
|---|---|---|
| Header | {"alg":"HS256","typ":"JWT"} | 签名算法和类型 |
| Payload | {"sub":"1234567890","name":"John Doe","iat":1516239022} | 实际数据,别放敏感信息! |
| Signature | 对前两部分的签名 | 防篡改用的 |
注意:Payload只是Base64编码,不是加密!谁都能解码看到内容。我曾经见过有人把密码直接放Payload里……这跟把钥匙挂门上有什么区别?
JWT最大的好处是无状态。服务器不需要存会话,拿到令牌一验签名就知道你是谁。这在微服务架构里特别爽,每个服务都能独立验证。
但坑也不少。比如令牌一旦签发,在过期前没法撤销。我有个项目就踩过这个坑——用户改了密码,但旧的JWT还能用半小时,气得产品经理直跳脚。后来我们加了黑名单机制才解决。
3.3 Session vs Token:选哪个?
这个问题几乎每次面试都会被问到。我直接给你对比表:
| 维度 | Session | Token(JWT) |
|---|---|---|
| 存储位置 | 服务器内存/Redis | 客户端(浏览器/App) |
| 扩展性 | 差,需要共享Session | 好,天然分布式 |
| 安全性 | 高,可随时销毁 | 中等,过期前难撤销 |
| 性能 | 每次请求查存储 | 本地验证,更快 |
| 跨域 | 麻烦,需配置 | 天然支持 |
| 典型场景 | 传统Web应用 | API、移动端、微服务 |
你想想看,如果你的系统是单体应用,用户量不大,Session完全够用。但如果是分布式架构,或者要给第三方提供API,那Token几乎是唯一选择。
我的建议:
- 内部管理系统 → Session,简单可靠
- 开放API → JWT,灵活扩展
- 移动端 → JWT,避免Cookie麻烦
- 高安全场景 → Session + Token双保险
3.4 实战中的避坑指南
做了这么多年,我总结了几条血泪教训:
- JWT别太大——Payload里别塞太多东西,不然每次请求都带着几百字节的令牌,网络开销受不了
- 过期时间别设太长——我习惯Access Token 15分钟,Refresh Token 7天。既保证体验,又降低风险
- 一定要用HTTPS——这不用我多说了吧?明文传输令牌等于裸奔
- 签名密钥定期换——我曾经有个项目密钥用了两年没换,后来被安全审计揪出来,尴尬得要死
最后说一句:身份认证没有银弹。Session也好,Token也罢,选适合你场景的就行。别为了炫技用JWT,也别因为保守死守Session。技术是工具,解决问题才是目的。