无需登录 数据私有 本地保存

OAuth流程模拟器 - 授权码/PKCE演示

10
0
0
0

OAuth 2.0 流程模拟器

交互式演示授权码流程 (Authorization Code) 与 PKCE 扩展

就绪
流程步骤
步骤详情
点击左侧步骤查看

👆 点击左侧步骤或使用下方控制按钮开始演示

常见问题与知识点
什么是 OAuth 2.0 授权码流程 (Authorization Code Flow)?

授权码流程是 OAuth 2.0 中最经典、最安全的授权方式之一。它通过前端通道获取授权码,后端通道换取令牌的双通道机制来保障安全:

  • 步骤1-3(前端通道):用户浏览器重定向到授权服务器,用户登录授权后,授权服务器通过浏览器回调返回一个短期有效的一次性授权码
  • 步骤4(后端通道):客户端服务器使用该授权码,配合 client_secret,通过服务器到服务器的 HTTPS 请求向授权服务器换取 access_token。
  • 安全优势:access_token 永远不会暴露在浏览器地址栏或浏览器历史中,只有后端服务器能获取。

此流程适用于有后端服务的 Web 应用(如传统 MVC 应用、后端渲染的应用),因为需要安全存储 client_secret。

PKCE (Proof Key for Code Exchange) 是什么?为什么需要它?

PKCE(读作 "pixy")是授权码流程的安全增强扩展,专为无法安全存储 client_secret 的公共客户端设计(如单页应用 SPA、移动 App、桌面应用)。

核心机制:

  • 客户端在发起授权请求前,先生成一个随机字符串 code_verifier(43-128字符),并计算其 SHA256 哈希的 Base64URL 编码作为 code_challenge
  • 授权请求中携带 code_challenge,授权服务器存储它。
  • 在换取令牌时,客户端必须提交原始的 code_verifier,服务器验证 SHA256(verifier) 是否等于之前存储的 challenge。

防护场景:在移动端或 SPA 中,恶意应用可能拦截回调 URL 中的授权码。但没有 code_verifier,攻击者无法完成令牌兑换。PKCE 有效防止了授权码拦截攻击。

code_verifier 和 code_challenge 之间是什么关系?

它们之间的关系可以用以下公式表示:

code_challenge = Base64URL( SHA256( code_verifier ) )

  • code_verifier:客户端生成的随机高熵字符串(推荐使用 43-128 字符的随机字符串),必须保密,仅客户端持有。
  • code_challenge:对 verifier 进行 SHA256 哈希后 Base64URL 编码的结果,可以公开传输(在授权请求 URL 中发送)。
  • 单向性:从 challenge 无法反推 verifier(SHA256 的单向性),确保即使 challenge 被截获,攻击者也无法完成令牌兑换。

PKCE 也支持 plain 模式(challenge = verifier),但强烈不推荐,应始终使用 S256 模式。

OAuth 2.0 中 state 参数的作用是什么?

state 参数是一个随机生成的字符串,在授权请求中发送,授权服务器在回调时原样返回。它有两大作用:

  • CSRF 防护:防止跨站请求伪造攻击。客户端验证回调中的 state 是否与请求时一致,确保授权响应对应的是自己发起的请求。
  • 状态保持:可以在 state 中编码一些应用状态信息(如用户原本访问的页面 URL),在回调后恢复用户的操作上下文。

最佳实践中,state 应该是不可预测的随机值,并应在使用后立即失效。

什么是 JWT (JSON Web Token)?如何解析它?

JWT 是一种紧凑的、URL 安全的令牌格式,由三部分组成,用点号 (.) 分隔:

eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxMjMifQ.signature_here

  • Header(头部):Base64URL 编码的 JSON,包含算法类型(如 RS256、HS256)和令牌类型(JWT)。
  • Payload(载荷):Base64URL 编码的 JSON,包含声明(claims),如 sub(主体)、iat(签发时间)、exp(过期时间)等。
  • Signature(签名):对前两部分使用指定算法和密钥生成的签名,用于验证令牌完整性和来源。

JWT 的内容可被任何人解码读取(Base64 不是加密),因此绝不能在 JWT 中存储敏感信息。安全性依赖于签名验证。

SPA(单页应用)应该使用哪种 OAuth 流程?

对于 SPA 和纯前端应用,推荐使用授权码流程 + PKCE(Authorization Code with PKCE),原因如下:

  • 不能使用传统授权码流程:SPA 无法安全存储 client_secret(代码完全暴露在浏览器中)。
  • 不应使用隐式流程:隐式流程(Implicit Flow)曾用于 SPA,但 access_token 直接暴露在 URL 片段中,安全风险较高,已被 OAuth 2.1 草案废弃
  • PKCE 解决了核心问题:即使没有 client_secret,PKCE 通过 code_verifier 的动态验证机制保证了安全性。

配合 BFF(Backend for Frontend) 架构或 Token Handler 模式,可以进一步提升 SPA 的安全性。

授权码 (Authorization Code) 可以重复使用吗?

不可以。授权码是一次性的,使用后立即失效。这是 OAuth 2.0 安全模型的重要设计:

  • 授权码有效期通常很短(30秒到10分钟),超时后未使用也会自动失效。
  • 一旦授权码被用于换取 access_token,授权服务器会立即将其标记为已使用或删除。
  • 如果攻击者截获了授权码但客户端已经使用过,攻击者的重放请求会被拒绝。
  • 授权服务器必须实施授权码的单次使用策略,这是 RFC 6749 的强制要求。
PKCE 的 code_verifier 应该如何生成才安全?

生成安全的 code_verifier 需要遵循以下规范(RFC 7636):

  • 长度:最少 43 字符,最多 128 字符。推荐使用 64-128 字符
  • 字符集:只能使用未保留字符:A-Z a-z 0-9 - . _ ~(即 Base64URL 字符集)。
  • 随机性:必须使用密码学安全的随机数生成器(如 crypto.getRandomValues()),不可使用 Math.random()。
  • 熵:43字符的verifier约有256位的熵,足以抵抗暴力破解。

本模拟器中使用 crypto.getRandomValues() 生成符合规范的随机 verifier,展示了最佳实践。