第3章 认证与授权基础:、Session、OAuth2、JWT

聊细粒度权限前,得先把地基打牢。
说白了,就是搞明白两个问题:你是谁?你能干什么?
我见过不少团队把认证和授权混着用,结果后面重构时改得头皮发麻。
嗯,咱们一步步来。

3.1 核心概念:认证 vs 授权

先把这个分清楚。

概念核心问题生活类比技术例子
认证(Authentication)你是谁?出示身份证登录名+密码,验证通过发
授权(Authorization)你能做什么?身份证查出你能否进VIP室里解析出角色,检查是否有读写权限

我见过最典型的错误:登录成功后,直接把用户所有数据扔给前端,让前端自己判断能不能点哪个按钮。
这哪是授权?这是裸奔。

3.2 Session 认证:经典的有状态方案

Session,这是最古老也最直观的方式。
原理特别简单:用户登录后,服务端开个房间(Session),房间号(Session ID)交给前端存Cookie。
下次请求带上门牌号,服务端就知道是谁来了。

我在项目中遇到过的一个坑:
一个老系统的Session全存在单台Tomcat内存里。后来业务量上来,搞了负载均衡。
结果用户第一次请求落到A机器,第二次落到B机器,Session丢了。
用户一脸懵,后台疯狂报错。

  • 优点:服务端完全可控,踢人、改状态都很方便。
  • 缺点:有状态,扩展起来得配Session共享(Redis或数据库),服务器开销大。

别把Session依赖当作默认选项。微服务环境下,Session同步的复杂度会让你很痛苦。
我建议:如果是单体应用,用Session没问题。一旦考虑水平扩展,趁早换方案。

3.3 认证:无状态的主力

说白了就是一张通行证。
用户登录后,服务端签发一个字符串,前端存起来(localStorage或内存),每次请求塞在Header里。
服务端不用存Session,直接验证就能知道用户信息。

为什么我更喜欢?因为它天生适合分布式。
每个服务只要拿到,自己能验,不用回调一个中心节点。省去了Session共享的麻烦。

注意的安全存储。别傻乎乎存Cookie里被XSS扫走。
我个人习惯:Access 存内存,Refresh 存httpOnly Cookie,两个配合用。

3.4 JWT:自包含的规范

JWT是的一种具体实现。
你可以把它理解成一种“自带简历”的——把用户ID、过期时间、角色签名后打包成三段字符串。
结构:Header(算法类型).Payload(用户数据).Signature(防篡改签名)。

// JWT生成示例(Node.js jsonwebtoken库)
const jwt = require('jsonwebtoken');
const payload = { userId: 123, role: 'admin' };
const secret = '你的密钥';
const  = jwt.sign(payload, secret, { expiresIn: '1h' });
console.log();
// 输出: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9.abc123...
  • 优点:无状态、跨语言、信息自包含。
  • 缺点:Payload纯文本,敏感数据别放进去;一旦签发,无法主动作废(除非搞个黑名单,那就又变成有状态了)。

我曾经见过把用户密码直接塞JWT Payload里的骚操作。
Base64解码就能看到,这跟把密码贴在脑门上有什么区别?
Payload只放非敏感字段:用户ID、角色、过期时间。

3.5 OAuth2:授权框架,不是认证协议

很多人把OAuth2当成登录方案,不对。
OAuth2是授权框架。它解决的是:第三方应用怎么替用户拿资源。
典型场景:你点“用微信登录”,微信不会把账号密码给网站,而是给个临时令牌,网站拿着令牌去调微信API拿你的昵称头像。

四个角色:

  1. 资源所有者(用户)
  2. 客户端(第三方应用)
  3. 授权服务器(发令牌的地方)
  4. 资源服务器(存数据的接口)

几种授权模式,我用过实战的就两种:

模式适用场景我踩过的坑
授权码模式有后端的Web应用最安全,但流程复杂,得跳转两次
客户端凭证模式服务端之间通信(M2M)没有用户参与,只认应用身份

微服务间调用,我经常用OAuth2客户端凭证模式+JWT。
每个服务持有一个Client ID和Secret,去授权服务器换,再用调其他服务。
这样每个接口不用重复鉴权,验一次就行。

3.6 四种机制选型对比

机制状态跨域支持安全性复杂度推荐场景
Session有状态差中低单体系统、传统Web
(无状态)无状态好中中SPA、移动端、分布式
JWT无状态好高中微服务、API网关
OAuth2有/无混合优秀高高第三方登录、开放API

你想想看,你的系统到底需要什么?
如果只是内部系统,用户少且固定,Session够用。
如果是对外API或者跨团队协作,JWT+OAuth2是更稳妥的选择。

我通常给一个实战组合建议:
用户登录走OAuth2授权码模式拿JWT
后续请求带JWT,网关验签,服务间调沿用JWT
需要强时效就配合Refresh 轮换
这样一套下来,认证、授权、安全全占齐。

认证与授权核心知识图谱 认证与授权四种机制关系图 用户 API Gateway 授权服务器 (OAuth2) 认证服务 Session仓库 JWT 签发 资源服务器 (接口) Session: 有状态,依赖服务端会话仓库 | /JWT: 无状态,自验证 | OAuth2: 授权框架,分发令牌

这张图展示的就是咱们这一章的核心流程。
从用户请求进来,经过API Gateway分流,走到认证服务和授权服务器。
Session负责存状态,JWT负责自验证,OAuth2负责分发。
最后所有请求统一到资源服务器干活。

搞明白这些基础,后面讲细粒度控制你才看得懂。
否则一上来就加密接口、权限下沉,你很容易懵。
嗯,这一章就到这儿。多想想你的业务属于哪种场景,选对方案比调优重要得多。