OAuth 2.0 vs JWT 区别 — 4 维度对比 + 实战选型指南
📅 2026 年 1 月更新 · DevToolbox 博客 · 预计阅读 12 分钟
认证 vs 授权,是每个后端开发者必须跨过的一道坎。而在面试和实际项目中,被问得最多的两个概念就是 OAuth 2.0 和 JWT。它们经常被混为一谈:有人说"JWT 就是 OAuth",也有人说"OAuth 一定要用 JWT"。事实上,它们根本不是同一层东西——OAuth 2.0 是一种授权框架(Authorization Framework),JWT 是一种令牌编码格式(Token Format),两者既可以单独使用,也能强强联合。本指南将带你从定义、流程、4 维度对比、实战选型 5 个角度彻底搞清它们的区别与联系,无论你是要面试、要设计登录系统,还是想给微服务加上 API 鉴权,都能在这里找到答案。
本文关键词:OAuth 2.0 教程、JWT 教程、access_token、refresh_token、单点登录 SSO、API 鉴权、认证 vs 授权。
一、OAuth 2.0 完全解析
OAuth 2.0(Open Authorization 2.0)是一个授权框架,不是认证协议。它解决的核心问题是:第三方应用如何在不获取用户密码的前提下,获得对用户资源的有限访问权限。RFC 6749 定义了它的标准协议。OAuth 2.0 不关心"你是谁"(那是认证),只关心"你被允许做什么"(那是授权)。想理解认证,可以看 JWT 完全指南。
1.1 OAuth 2.0 的 4 种角色
- Resource Owner(资源所有者):就是用户本人,掌控自己数据的访问权。
- Client(客户端):想要访问用户资源的第三方应用,比如"用 GitHub 登录"的那个网站。
- Authorization Server(授权服务器):负责颁发 access_token 的"发证机构",例如 GitHub、Google、Okta。
- Resource Server(资源服务器):真正存放用户数据的 API 服务,只认 access_token。
1.2 OAuth 2.0 的 4 种授权模式(Grant Type)
- Authorization Code(授权码模式):最常用、最安全的标准流程,适合有后端的 Web 应用。流程是用户先被跳到授权服务器登录确认,授权服务器回跳带回一个短期 code,客户端再用 code + client_secret 换取 access_token。
- Implicit(隐式模式):曾用于纯前端 SPA,OAuth 2.1 已正式废弃,统一改用 Authorization Code + PKCE。
- Client Credentials(客户端凭证模式):没有用户参与的服务间调用,例如微服务 A 调微服务 B 的内部 API,机器对机器(M2M)场景首选。
- Resource Owner Password Credentials(密码模式):直接用用户名密码换 token,已不推荐,仅在自家高可信第一方应用的历史迁移中偶尔使用。
1.3 OAuth 2.0 授权码流程图
┌────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户 │ │ 第三方App │ │ 授权服务器│ │ 资源服务器│
└───┬────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ ① 点击"用 GitHub 登录" │ │ │
│ ─────────────────────────▶│ │ │
│ │ ② 跳转 GitHub 授权页 │ │
│ │ ────────────────────────────▶│ │
│ ③ 输入账号密码、点"授权" │ │ │
│ ◀────────────────────────────────────────────────────────│ │
│ ④ 跳转回 App 并带 code │ │ │
│ ─────────────────────────▶│ │ │
│ │ ⑤ POST /token (code+secret)│ │
│ │ ────────────────────────────▶│ │
│ │ ⑥ 返回 access_token │ │
│ │ ◀────────────────────────────│ │
│ │ ⑦ GET /user (Bearer token) │
│ │ ──────────────────────────────────────────────────────────▶│
│ │ ⑧ 返回用户数据 │
│ │ ◀──────────────────────────────────────────────────────────│
└────────┘ └──────────┘ └──────────┘ └──────────┘
1.4 真实场景:用 GitHub 登录第三方网站
你在 Vercel 上部署博客时,点"Continue with GitHub"——浏览器跳到 GitHub,你点同意,Vercel 拿到 access_token 就能调 GET https://api.github.com/user 读你的公开邮箱、头像、仓库列表。整条链路上 Vercel 永远拿不到你的 GitHub 密码,这就是 OAuth 2.0 授权框架的核心价值。单点登录 SSO、第三方登录、跨应用 API 授权都是它的典型落地场景。
1.5 OAuth 2.0 的优缺点
优点:① 标准化,跨平台、跨语言、跨云厂商通用;② 用户密码不外泄,安全等级高;③ 可做细粒度 scope 权限控制(如只读邮箱、只读仓库);④ 天然适合做单点登录 SSO 和第三方登录。
缺点:① 协议本身相对复杂,新手容易和 OpenID Connect (OIDC) 混淆;② access_token 一旦签发,撤销需要引入额外机制(黑名单/短 exp);③ 严格实现需要支持 PKCE、State、redirect_uri 白名单等安全细节。
二、JWT 完全解析
JWT(JSON Web Token,RFC 7519)是一种紧凑的、自包含的令牌格式。它把一段 JSON 声明(claims)经过 Base64URL 编码 + 数字签名后,变成一串 eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxw 这样的字符串,可放在 HTTP Header、URL 参数或 Cookie 中传递,服务端用密钥验签就能判断"这个 token 是不是我发的、有没有被改过"。
2.1 JWT 的三段式结构:Header.Payload.Signature
| 段 | 内容 | 作用 |
|---|---|---|
| Header | alg + typ | 声明签名算法(HS256 / RS256 / ES256) |
| Payload | claims(iss/sub/exp/iat/...) | 存放用户信息、过期时间等业务数据 |
| Signature | 前两段 + secret 算出的签名 | 防篡改,是 JWT 安全核心 |
三段之间用英文句点 . 连接,例:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c,可粘到 JWT 解码工具 实时看到每段含义。
2.2 JWT 的鉴权流程
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 客户端 │ │ 鉴权服务 │ │ 业务 API │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ ① POST /login (user, pwd) │ │
│ ──────────────────────────────────────────▶│ │
│ │ ② 校验密码、生成 JWT(exp=2h) │
│ ③ 返回 { access_token, refresh_token } │ │
│ ◀──────────────────────────────────────────│ │
│ │
│ ④ GET /api/orders │
│ Authorization: Bearer eyJhbG... │
│ ────────────────────────────────────────────────────────────────────────────────────▶│
│ │ │ ⑤ 验签 + 检查 exp
│ │ │ 从 sub 取 user_id
│ ⑥ 200 OK { orders: [...] } │
│ ◀────────────────────────────────────────────────────────────────────────────────────│
│ │
│ ⑦ 2h 后 access_token 过期 → 用 refresh_token 换新 │
│ ⑧ POST /refresh (refresh_token) │ │
│ ──────────────────────────────────────────▶│ │
│ ⑨ 返回新 access_token │ │
│ ◀──────────────────────────────────────────│ │
└──────────┘ └──────────┘ └──────────┘
2.3 JWT 的优点
① 无状态(Stateless):服务端不用存 session,token 自包含用户信息,天然适合分布式 / 微服务。
② 跨域友好:放在 Authorization Header 里就能跨域、跨服务、跨语言传递。
③ 移动端友好:iOS / Android / 小程序都能用,Cookie 反而更麻烦。
④ 自包含:payload 里就能放 user_id、role、scope,减少数据库查询。
2.4 JWT 的缺点
① 难以撤销:token 签发后到过期前都有效,要"踢人下线"必须额外加黑名单或短 exp。
② Payload 不加密:只是 Base64URL 编码,任何拿到 token 的人都能直接解码看到原文,绝不能放密码、身份证。
③ 密钥泄露风险:HS256 一旦 secret 泄露,攻击者可签任意 token;必须用 httpOnly Cookie + HTTPS + 短 exp + refresh token 组合规避。
2.5 实战:解码你的第一个 JWT
想看一个真实 JWT 长啥样?把这段贴到 DevToolbox JWT 解码器:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
立刻看到 Header 的 alg: HS256、Payload 的 sub / name / iat。纯浏览器本地解码,不会上传,放心用。
三、OAuth 2.0 vs JWT:4 维度深度对比
网上很多文章把 OAuth 2.0 和 JWT 当作"竞争关系"对比,这是误区。它们一个是协议层,一个是数据层,不是同一抽象级别。下面从 4 个关键维度拆开看。
| 对比维度 | OAuth 2.0 | JWT |
|---|---|---|
| 维度 1:定位 | 授权框架(Protocol) | 令牌格式(Format) |
| 维度 2:状态 | 通常有 state 参数防 CSRF | 无状态,token 自证身份 |
| 维度 3:典型场景 | 第三方登录、SSO、跨应用授权 | API 鉴权、微服务、移动端 |
| 维度 4:组合使用 | 颁发 access_token(JWT 格式) | 作为 OAuth 的 token 载体 |
| 数据存储 | 服务端可存 token 状态(可撤销) | 不存(撤销需黑名单) |
| 复杂度 | 高(4 种 grant type + PKCE + scope) | 低(签发 + 验签 2 个动作) |
| 标准 | RFC 6749 / RFC 8252 / OAuth 2.1 | RFC 7519 |
3.1 维度 1:定位(Protocol vs Format)
OAuth 2.0 解决的是"流程问题":用户、客户端、授权服务器、资源服务器四方之间怎么一步步交互,谁先发请求、谁回什么参数、跳几次 URL、HTTP 状态码怎么定——这是协议层的抽象。JWT 解决的是"数据问题":token 怎么编码、用什么签名、字段怎么放、怎么防篡改——这是数据格式层的抽象。两者抽象层级完全不同:OAuth 2.0 可以用 JWT 当 access_token,也可以用随机字符串 opaque token。
3.2 维度 2:状态(Stateful vs Stateless)
OAuth 2.0 在授权码交换这一步必须传 state 参数来防 CSRF,授权服务器端也会存短期 code 和 access_token 状态,因此整体是有状态的。JWT 则彻底无状态,token 一旦签发就"自我证明",不依赖服务端存储。代价是 JWT 撤销困难,必须靠短 exp + refresh token + 黑名单 三件套兜底。
3.3 维度 3:典型场景
OAuth 2.0 适合:第三方登录(GitHub/Google/微信登录)、企业 SSO(一个账号登 N 个内部系统)、跨应用 API 授权(合作伙伴系统调用你的 API)、OpenID Connect 身份认证层。
JWT 适合:前后端分离的 API 鉴权、微服务间调用鉴权、移动端 App 鉴权、短生命周期 access_token、分布式系统无状态会话。
3.4 维度 4:组合使用(生产环境的最佳拍档)
现代系统几乎都是 OAuth 2.0 颁发 JWT 格式的 access_token:
① 客户端走 OAuth Authorization Code 流程拿到 code;
② 授权服务器颁发 access_token(JWT 格式,短 exp=15min) + refresh_token(opaque 长 exp=7d);
③ 客户端调业务 API 时,Header 带 Authorization: Bearer eyJhbG...;
④ 资源服务器用公钥(RS256)验签 JWT,检查 exp / aud / scope,无需再调授权服务器查状态;
⑤ access_token 过期后用 refresh_token 换新。
这就是 Auth0、Okta、Keycloak、AWS Cognito 等主流身份服务的默认实现。
四、实战选型指南:4 个真实场景怎么选?
讲完理论,最关键的问题还是:我的项目到底该用 OAuth 2.0、JWT、还是两者都用?下面给 4 个最常见场景的明确答案。
例如公司内部 OA、博客、CRM。直接用 JWT 就够:用户密码登录 → 后端签 access_token (JWT) + refresh_token → 前端存 token 调 API。不用引入 OAuth 2.0,省掉授权服务器、redirect_uri、scope 等复杂度,2 小时就能搭起来。
任何涉及"第三方登录"的场景都必须用 OAuth 2.0。推荐 Authorization Code + PKCE 模式,授权服务器选 GitHub Apps、Google Identity Platform、微信开放平台。拿到 GitHub 返回的 user 信息后,再 自己签发一对 JWT token 给前端用。
最常见的大型系统架构。推荐 OAuth 2.0 颁发 JWT:用 Keycloak / Auth0 / 自研 OIDC 服务做授权服务器,下发
access_token (JWT, exp=15min) + refresh_token (exp=7d)。前端 Web / iOS / Android / 小程序都能用,资源服务器用公钥 RS256 验签,零状态、高性能。
没有用户参与的服务对服务调用,例如订单服务调支付服务。首选 OAuth 2.0 Client Credentials 模式,或直接用 JWT 短期 token + mTLS。Istio/Envoy 等服务网格默认就用 JWT 做服务间鉴权。
🏆 终极推荐组合:OAuth 2.0 Authorization Code + PKCE 颁发 access_token (JWT / RS256, exp=15min) + refresh_token (opaque, exp=7d, 存服务端可主动撤销)。这是 2026 年现代 Web / 移动应用鉴权的事实标准。
五、常见问题 FAQ
Q1:OAuth 2.0 安全吗?
协议本身安全,前提是实现到位。必须做:① 全程 HTTPS;② 强制 PKCE(防 code 截获);③ state 参数防 CSRF;④ redirect_uri 严格白名单;⑤ client_secret 不进前端;⑥ access_token 短 exp + refresh_token 轮换。只要按 RFC 8252 和 OAuth 2.1 草案做,OAuth 2.0 是工业级安全的。
Q2:JWT 怎么撤销?
三种思路:① 短 exp + refresh token(最常用,access_token 15 分钟过期,refresh_token 7 天,泄露损失可控);② 黑名单(把要撤销的 jti 存 Redis,校验前先查);③ 密钥轮换(服务端突然换 secret,所有老 token 全部失效)。实际项目里 ① + ② 组合用最稳。
Q3:OAuth 2.0 和单点登录 SSO 是什么关系?
OAuth 2.0 是底层授权框架,单点登录 SSO 是它的一种典型应用形态。严格的 SSO 标准叫 OpenID Connect (OIDC)——它在 OAuth 2.0 之上加了 id_token(JWT 格式)和 /userinfo 端点,让授权服务器能"顺带"告诉你"登录的人是谁"。所以记一句话:OIDC = OAuth 2.0 + 身份认证,要做企业 SSO 就上 OIDC。
Q4:JWT 和 Session Cookie 区别?
Session Cookie 是有状态的:服务端存 session,cookie 里只带 sessionId,关掉浏览器就过期。JWT 是无状态的:服务端不存东西,token 自包含用户信息。Session 优势在撤销简单,JWT 优势在分布式友好。两者可以结合用:把 JWT 放在 httpOnly + Secure + SameSite 的 Cookie 里,兼顾安全和易用。
Q5:移动端用 OAuth 2.0 还是 JWT?
两者都离不开。登录授权用 OAuth 2.0(Authorization Code + PKCE,移动端不能放 client_secret,必须用 PKCE 防截获);后续 API 调用用 JWT(access_token + refresh_token,存 iOS Keychain / Android EncryptedSharedPreferences,绝不放 localStorage / UserDefaults)。
六、写在最后:DevToolbox 开发者工具箱
读到这里,你应该已经彻底分清 OAuth 2.0 和 JWT 了。一句话总结:OAuth 2.0 解决"怎么授权",JWT 解决"token 长啥样",现代系统最常见的组合就是"用 OAuth 2.0 颁发 JWT token"。
如果你想立刻动手验证一个 JWT 的内容,DevToolbox 提供 100+ 款免费在线开发者工具,全部纯前端本地处理、零数据上传。下面这些工具和今天的鉴权主题强相关:
🛠 鉴权与编码类工具
- 🔐 JWT 解码器 — 粘 token 立即看到 Header / Payload / Signature,验签一气呵成
- 🔤 Base64 编解码 — JWT 三段都是 Base64URL 编码,理解 JWT 的前置基础
- 🔗 URL 编解码 — OAuth redirect_uri / query 参数处理必备
- 🆔 UUID 生成器 — JWT jti 声明、refresh_token 唯一标识随手生成
📄 文档处理类工具
- 📎 PDF 合并 — 把多个 PDF 合同/报告一键合并成一份,OAuth 授权文档归档常用
- 🔒 PDF 加密 — 给含 access_token 的文档加密码保护,防泄露
- 📝 PDF 转 Word — 把扫描的 OAuth 协议 RFC 文档转成可编辑 Word
- 📦 PDF 压缩 — 鉴权设计文档太大?无损压缩到 1MB 以内方便邮件发送
📚 相关文章:JWT 完全指南 · JWT Refresh Token 深度解析 · Base64 编码完全指南 · URL 编码完全指南 · 在线 JWT 解码工具