直接答案:2026 年的 OAuth 迁移不再是“要不要用 OAuth”,而是“按哪一版规则收紧”。RFC 9700(BCP 240,2025)把多年最佳实践写成 MUST/SHOULD:授权码流必须配 PKCE(S256)、重定向 URI 精确匹配、禁止 open redirector、公共客户端 refresh token 必须发送方约束或轮换、访问令牌应做 audience 限制、资源服务器必须拒绝错误 audience。RFC 10017(BCP 212,2026-08)进一步把浏览器应用分成 BFF(最安全)→ token-mediating backend → browser-based OAuth client(最暴露),并明确指出浏览器存储无法保证加密、XSS 可窃取令牌。OAuth 2.1 草案 -17(2026-10-30)则把上述规则固化:PKCE 成为默认、Implicit 与 ROPC 被移除、bearer token 不再放 query、PKCE plain 被禁止。注意:OAuth 2.1 尚未成为 RFC,不要把“草案兼容”写成“已认证”。
本文面向 SaaS/API、身份认证、前后端和安全团队,解释 RFC 9700、RFC 10017 与 OAuth 2.1 草案的变化、BFF/浏览器客户端选型、PKCE/重定向/refresh token/audience/mix-up 的实施要求、常见失败模式和 90 天迁移清单。规则来自 IETF RFC 9700(BCP 240)、RFC 10017(BCP 212)、OAuth 2.1 draft-ietf-oauth-v2-1-17(2026-10-30)及 RFC 7636/9207/9449,均于 2026-11-08 访问。本文把“官方规则事实”“编辑建议”和“待确认项”分开写,不构成合规或采购建议。
① PKCE 是默认:授权码流用 S256;public client 必须,confidential client 推荐;plain 在 OAuth 2.1 被禁止。② 浏览器里“存 token”不是架构:BFF 把 token 留在服务端 cookie session,token-mediating backend 次之,纯浏览器客户端最暴露。③ 迁移顺序:清点客户端/流 → PKCE + 精确 redirect → 去 Implicit/ROPC → refresh 轮换/发送方约束 → audience/iss 校验 → BFF/令牌存储。
版本与时间线:9700、10017、OAuth 2.1 草案
RFC 9700 是 OAuth 2.0 的安全最佳实践(BCP 240),更新/扩展 RFC 6749/6750/6819 的威胁模型,并把部分模式标为不安全;RFC 10017 是浏览器应用(SPA/JS)的 BCP(BCP 212,2026-08),给出 BFF、token-mediating backend、browser-based client 三种架构;OAuth 2.1 草案 -17 在 2026-10-30 更新,计划替代 RFC 6749/6750,但仍是 Internet-Draft(2027-05 过期),不是 RFC。三者关系是:9700 是“现在就该做”的安全基线,10017 是“浏览器怎么做”,2.1 是把两者固化后的下一版框架。
| 文档 | 状态/日期 | 对迁移的意义 |
|---|---|---|
| RFC 6749 / 6750 | 2012 / 2012 | OAuth 2.0 基础;部分模式已不安全 |
| RFC 9700 | BCP 240,2025 | PKCE、精确 redirect、refresh 轮换/发送方约束、audience、mix-up |
| RFC 10017 | BCP 212,2026-08 | BFF / token-mediating / browser client 架构与令牌存储 |
| OAuth 2.1 draft -17 | 2026-10-30,草案 | PKCE 默认、Implicit/ROPC 移除、bearer 不进 query、plain 禁止 |
| RFC 7636 / 9207 / 9449 | PKCE / iss / DPoP | PKCE S256、mix-up 防护、发送方约束 |
来源:IETF RFC 9700、RFC 10017、OAuth 2.1 draft-ietf-oauth-v2-1-17(2026-10-30)、RFC 7636/9207/9449(访问 2026-11-08)。表中为编辑整理;OAuth 2.1 仍是草案,最终条款可能变化。
OAuth 2.1 草案相对 2.0 的关键变化
草案把“最佳实践”变成默认规则:授权码流默认要求 PKCE 的 code_challenge/code_verifier;重定向 URI 必须精确字符串匹配;Implicit(response_type=token)与 ROPC 被移除;bearer token 不再允许放在 URI query;public client 的 refresh token 必须发送方约束或一次性使用;浏览器类 refresh token 还有额外生命周期约束;PKCE plain 被明确禁止;token endpoint 在授权码交换时不再需要 redirect_uri。对现有系统,这些不是“可选项”,而是互操作门槛。
| 主题 | OAuth 2.0 / 旧实现 | OAuth 2.1 草案 |
|---|---|---|
| PKCE | 可选扩展 | 授权码流默认必需;AS 必须支持/强制 |
| PKCE plain | 可用 | 明确禁止;用 S256 |
| 重定向 URI | 可前缀/通配匹配 | 精确字符串匹配(localhost 端口例外) |
| Implicit | 可用 | 移除(response_type=token) |
| ROPC | 可用 | 移除 |
| Bearer in query | 可用 | 不再使用;走 header |
| Public client refresh | 可长期固定 | 发送方约束或一次性使用/轮换 |
| iss / mix-up | 可选 | AS 发 iss;客户端做 mix-up 防护 |
来源:OAuth 2.1 draft-ietf-oauth-v2-1-17 §1.8/§10/变更列表(2026-10-30);RFC 9700 §2.1/§4。表中为编辑整理;具体 MUST/SHOULD 以草案原文为准。
浏览器架构选型:BFF、token-mediating、browser client
RFC 10017 按安全性从高到低给出三种模式:BFF 由后端作为 confidential client 完成 OAuth、把 access/refresh token 放在服务端 cookie session、所有 API 请求经 BFF 转发,浏览器拿不到 token;token-mediating backend 由后端处理 OAuth,但浏览器拿 access token 直接调资源服务器;browser-based OAuth client 由浏览器作为 public client 完成全部 OAuth,token 存浏览器。后两者都暴露 token,XSS/恶意 JS 可窃取;BFF 用 HttpOnly cookie 降低会话劫持风险,是大多数新应用的首选。
| 模式 | token 在哪 | 安全性 | 适用 |
|---|---|---|---|
| BFF | 服务端 session/cookie;浏览器无 token | 最高 | 新 SPA、同域/跨域 API、敏感业务 |
| Token-mediating backend | 后端处理 OAuth;浏览器拿 access token 直连 API | 中 | 已有 API 直连、可接受 token 暴露 |
| Browser-based OAuth client | 浏览器 localStorage/sessionStorage/IndexedDB/内存 | 最低 | 无后端、低风险、可接受权衡 |
| 同域前后端 | 可不用 OAuth,用同站 cookie/session | 取决于实现 | 前后端同域、无第三方 API |
来源:RFC 10017 §6/§8/§9(2026-08);RFC 9700。表中为编辑整理;具体架构还受同域、CORS、CSP、第三方 API 约束。
迁移清单:从“能登录”到“按 2.1 收紧”
先做“能被审计”的清单:每个 client 的类型(public/confidential)、grant/response type、redirect URI、PKCE 方法、token 存储位置、refresh 策略、audience/scope、是否多 AS。然后按风险排序:PKCE+精确 redirect 是第一批;去 Implicit/ROPC 是第二批;refresh 轮换/发送方约束、audience/iss 校验是第三批;BFF/令牌存储是架构级改造,可并行。每项都要有回归测试和监控,不要一次全量切换。
| 领域 | 动作 | 验收证据 |
|---|---|---|
| PKCE | 授权码流加 S256 challenge/verifier;拒绝 plain | AS 强制;无 verifier 拒绝 |
| Redirect | 精确匹配;去掉通配/前缀;禁止 open redirector | 注册全 URI;负向测试 |
| Grant | 移除 Implicit/ROPC;改用 code+PKCE | 旧端点下线/告警 |
| Refresh | public client 轮换或 DPoP/mTLS;重用即撤销 | 重放测试、撤销日志 |
| Audience | access token 绑定资源服务器;RS 校验 aud/iss/exp | 错 audience 被拒 |
| Mix-up | 多 AS 客户端校验 iss;按 RFC 9207 | 错 issuer 中止 |
| Token 存储 | 优先 BFF/HttpOnly;浏览器避免持久化 token | XSS 演练、CSP |
| Bearer | 只用 Authorization header;不放 query | 日志/网关规则 |
编辑整理的迁移清单,不是官方模板;具体 MUST/SHOULD、兼容性和验收以 RFC 9700/10017、OAuth 2.1 草案和授权服务器文档为准。
常见失败模式:为什么“用了 OAuth”还会被盗
OAuth 的漏洞通常在实现细节:redirect URI 用前缀匹配、PKCE 用 plain 或只在客户端“假装”校验、token 放 localStorage 被 XSS 偷、refresh token 长期不轮换、access token 不校验 audience 导致“拿 A 服务的 token 调 B 服务”、多 AS 不校验 iss 被 mix-up、把 bearer token 放 query 进日志、JWT 只验签名不验 alg/iss/aud/exp、CORS 放太宽让恶意站点直接调用 API。OAuth 2.1 的收紧就是把这些坑逐条关掉。
| 失败模式 | 后果 | 控制 |
|---|---|---|
| redirect 前缀/通配 | 授权码/令牌被重定向到攻击者 | 精确匹配 + 注册全 URI |
| PKCE plain / 未强制 | 授权码注入/拦截 | S256 + AS 强制 + 拒绝无 verifier |
| token 放 localStorage | XSS 直接窃取 | BFF/HttpOnly;CSP;短寿命 |
| refresh 不轮换 | 长期重放 | 一次性/轮换 + 重用撤销 |
| audience 不校验 | 跨服务令牌滥用 | RS 校验 aud/iss/exp;资源绑定 |
| 多 AS 不校验 iss | mix-up 攻击 | RFC 9207 iss;逐 issuer redirect |
| bearer 放 query | 日志/Referer 泄漏 | 只用 Authorization header |
| JWT 校验不全 | alg 混淆/过期令牌 | 固定 alg、验 iss/aud/exp、密钥轮换 |
| CORS 过宽 | 恶意站点直连 API | 最小 origin 白名单 + CSP |
编辑整理的常见问题,不是官方清单;具体攻击/缓解以 RFC 9700、RFC 10017、RFC 9449/9207 和授权服务器文档为准。
90 天迁移清单
先用 90 天完成“清点、收口、验证”:第 1–2 周清点 client/流/token 存储;第 2–4 周上 PKCE S256 + 精确 redirect;第 4–6 周下线 Implicit/ROPC;第 6–8 周 refresh 轮换/发送方约束 + audience/iss 校验;第 8–10 周 BFF 或 token 存储改造;第 10–12 周做重放/XSS/错 audience 演练和监控。不要在没有回滚/监控的情况下一次性切换所有 client。
| 阶段 | 动作 | 产出 |
|---|---|---|
| 第 1–2 周 | 清点 client、grant/response type、redirect、PKCE、token 存储、AS 数量 | OAuth 资产清单、风险排序 |
| 第 2–4 周 | PKCE S256;AS 强制;精确 redirect;禁 open redirector | 授权码流加固、负向测试 |
| 第 4–6 周 | 下线 Implicit/ROPC;迁移到 code+PKCE | 旧流告警/关闭 |
| 第 6–8 周 | refresh 轮换/DPoP/mTLS;aud/iss/exp 校验 | 重放/错 audience 测试 |
| 第 8–10 周 | BFF/HttpOnly 或浏览器 token 存储改造;CSP/CORS | 架构改造、XSS 演练 |
| 第 10–12 周 | 监控/告警/回滚;更新文档与审计证据 | 运行手册、合规材料 |
编辑整理的迁移建议,不是官方模板;具体范围、优先级和验收以企业架构、RFC 9700/10017、OAuth 2.1 草案和授权服务器能力为准。
常见问题
OAuth 2.1 正式发布了吗?
没有。OAuth 2.1 仍是 Internet-Draft(draft-ietf-oauth-v2-1-17,2026-10-30,2027-05 过期),目标替代 RFC 6749/6750。现在应按 RFC 9700/10017 的 BCP 做,不要声称“已符合 OAuth 2.1”。
PKCE 是必须的吗?
RFC 9700 要求 public client 必须用 PKCE、confidential client 推荐;OAuth 2.1 草案把授权码流默认改为必须。用 S256,不要用 plain;AS 要强制校验 code_verifier。
Implicit 和 ROPC 还能用吗?
不应继续用。RFC 9700 把 Implicit 标为不应使用、ROPC 标为 MUST NOT;OAuth 2.1 草案直接移除。迁移到 authorization code + PKCE。
SPA 应该用 BFF 吗?
大多数新应用建议 BFF:后端作为 confidential client,token 留在服务端 cookie session,浏览器不接触 token。token-mediating backend 次之;纯 browser-based client 最暴露,只适合无后端/低风险场景。
refresh token 怎么保护?
public client 必须发送方约束(DPoP/mTLS)或一次性轮换;重用旧 refresh token 应撤销整条链。浏览器类 refresh token 还有额外生命周期约束(RFC 10017)。
为什么 access token 要 audience 限制?
防止“拿 A 服务的 token 调 B 服务”。RFC 9700 建议 access token 绑定特定资源服务器;资源服务器必须校验 aud/iss/exp,错误 audience 直接拒绝。
iss 参数是做什么的?
用于 mix-up 防护:客户端同时对接多个 AS 时,授权响应里的 iss 让客户端确认“这个 code 来自我预期的 issuer”。RFC 9700 推荐 RFC 9207;OAuth 2.1 草案要求 AS 发送 iss。
access token 能放 localStorage 吗?
风险高:XSS 可直接读取,浏览器存储也不保证加密。优先 BFF/HttpOnly;纯浏览器场景至少用内存/短寿命/发送方约束,并配合 CSP、CORS 最小化。
研究方法与局限
本文把“官方规则事实”和“编辑建议”分开:RFC 9700 的 PKCE/精确 redirect/refresh 轮换/发送方约束/audience/mix-up 要求,来自 IETF RFC 9700(BCP 240,2025);RFC 10017 的 BFF/token-mediating/browser client 架构、浏览器存储与 refresh 约束,来自 RFC 10017(BCP 212,2026-08);OAuth 2.1 的 PKCE 默认、Implicit/ROPC 移除、bearer 不进 query、plain 禁止、iss 等变化,来自 draft-ietf-oauth-v2-1-17(2026-10-30);PKCE/iss/DPoP 细节来自 RFC 7636/9207/9449。迁移清单、失败模式和 90 天计划为编辑整理。
局限有八个:① 不构成合规/法律建议;② OAuth 2.1 仍是草案,最终条款可能变化;③ 未逐一核对各授权服务器/库的实现差异;④ 未展开 OpenID Connect、PAR、JARM、Rich Authorization Requests 的细节;⑤ 未评估具体 SDK/框架的默认配置;⑥ 未做真实攻击/渗透测试;⑦ 未覆盖移动/原生/IoT 客户端的全部规则;⑧ 标准/实现会更新,落地前应复核 IETF/供应商文档。
数据来源与口径
- IETF RFC 9700, Best Current Practice for OAuth 2.0 Security(BCP 240,2025):rfc-editor.org/rfc/rfc9700。PKCE、精确 redirect、refresh 轮换/发送方约束、audience、mix-up。访问 2026-11-08。
- IETF RFC 10017, OAuth 2.0 for Browser-Based Applications(BCP 212,2026-08):rfc-editor.org/rfc/rfc10017。BFF/token-mediating/browser client、浏览器存储、refresh 约束。访问 2026-11-08。
- IETF OAuth 2.1 draft-ietf-oauth-v2-1-17(2026-10-30):datatracker.ietf.org/doc/draft-ietf-oauth-v2-1。PKCE 默认、Implicit/ROPC 移除、bearer 不进 query、plain 禁止。访问 2026-11-08。
- IETF RFC 7636(PKCE)、RFC 9207(iss)、RFC 9449(DPoP):rfc7636 / rfc9207 / rfc9449。PKCE S256、issuer 识别、发送方约束。访问 2026-11-08。
资料截止 2026-11-08;OAuth 规则以 IETF RFC/草案与授权服务器文档为准;本文不构成合规、法律或采购建议。