跳到主要内容
uencoder

如何Implement OAuth 2.0 PKCE Flow

Implement Proof 关键为 Code Exchange (PKCE) 扩展到 OAuth 2.0 Authorization Code flow 为安全公共客户端认证.

问题

公共 clients (SPAs, mobile apps) cannot 安全存储客户端 secret, making 它们 vulnerable 到授权代码 interception attacks. 你需要implement PKCE (RFC 7636) 到绑定授权代码到 代码 verifier known 仅到 客户端.

前置条件

  • Understanding 的 OAuth 2.0 Authorization Code flow
  • 熟悉公共 vs. confidential clients
  • Knowledge 的 SHA-256 哈希和 Base64URL 编码

步骤

  1. 1. Generate the code verifier and code challenge

    Generate a cryptographically random code verifier: a high-entropy string of 43-128 characters from the unreserved character set [A-Z][a-z][0-9]-._~. Then derive the code challenge: S256 method computes BASE64URL-ENCODE(SHA256(ASCII(code_verifier))). The code challenge is sent in the authorization request; the code verifier is kept locally and never sent until the token exchange. Use the random generator for the verifier and SHA-256 + Base64URL for the challenge.

    输入
    random 32 bytes -> base64url
    输出
    verifier: dBjftJeZ4CuK... | challenge: E9Melhoa2l2cYi8Yk... (S256)
  2. 2. Send the authorization request with code challenge

    Redirect the user to the authorization endpoint with parameters: response_type=code, client_id, redirect_uri, scope, state (CSRF protection), code_challenge, code_challenge_method=S256. The authorization server stores the code challenge associated with the issued authorization code. The state parameter must be a random value that the client validates on redirect to prevent CSRF.

    输入
    GET /authorize?response_type=code&client_id=app1&code_challenge=E9Mel...&code_challenge_method=S256&state=xyz
    输出
    redirect: https://app.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
  3. 3. Exchange the code with the code verifier

    On receiving the authorization code, send a token request to the token endpoint with: grant_type=authorization_code, client_id, code, redirect_uri, code_verifier. The authorization server recomputes BASE64URL(SHA256(code_verifier)) and compares it to the stored code challenge. If they match, the code was not intercepted — issue tokens. If they don't match, reject the request. Use the OAuth token parser to inspect the returned tokens.

    输入
    POST /token { grant_type, code, code_verifier: dBjftJeZ4CuK... }
    输出
    { access_token, refresh_token, token_type: Bearer, expires_in }
  4. 4. Validate tokens and secure the state parameter

    Validate the state parameter matches the one sent in step 2 to prevent CSRF. Parse the access token (if JWT) to check expiration, issuer, and audience. Store tokens securely: access token in memory, refresh token in secure storage (httpOnly cookie for web, secure enclave for mobile). Never store tokens in localStorage for SPAs. Use the JWT parser to verify token claims before using the token.

    输入
    access_token: eyJhbGciOi...
    输出
    valid: true | exp: 1234567890 | scope: read write

预期结果

安全 OAuth 2.0 PKCE flow where 公共 clients 认证无 客户端 secret, 受保护针对授权代码 interception 和 CSRF attacks.

常见错误

Using plain code_challenge_method instead of S256
The 'plain' method sends the verifier directly as the challenge, providing no protection if intercepted. Always use S256 (SHA-256 based).
Code verifier too short or not cryptographically random
The verifier must be 43-128 characters of high entropy. Use a CSPRNG (crypto.getRandomValues), not Math.random(). 32 random bytes base64url-encoded gives 43 characters.
Omitting or not validating the state parameter
The state parameter prevents CSRF. Generate it randomly, include in the auth request, and validate it exactly matches on the redirect.

排障指引

  • If the authorization server rejects the token request with 'invalid_grant', verify the code_verifier matches the code_challenge used in the authorization request.
  • For SPAs, consider using the Backend-For-Frontend (BFF) pattern instead of storing tokens in the browser, which is more secure than pure PKCE in the browser.
  • If using refresh tokens, implement token rotation (issue a new refresh token on each use) and detect reuse to revoke the token family.

安全限制

  • PKCE protects the authorization code exchange but does not protect the access token from XSS in the browser — use BFF pattern for higher security.
  • All token validation happens locally; the client never sends the code verifier to any party except the authorization server.
  • Access tokens in localStorage are vulnerable to XSS — prefer in-memory storage with silent refresh via refresh token.

相关工具

OAuth Token 解析器
Oauth Token Parser — 纯客户端工具。隐私优先,无服务器往返。
工具
JWT 解码器
解码并检查 JWT 头部、载荷和时间声明及过期状态。免费、隐私优先、100% 纯客户端运行。本地解析不视为服务端验签。支持 HS256/RS256 等算法头部解析、exp/iat/nbf 时间声明展示,并标注 EXPIRED/NOT YET VALID/VALID 状态。
工具
JWT 编码器
使用 HS256 编码 JWT。免费、隐私优先、100% 纯客户端运行。不用于服务端验签。
工具
Bearer Token 生成器
由 token 字符串构造「Bearer <token>」Authorization 头(RFC 6750)。token 会按 b64token 语法校验——字母、数字、-._~+/ 与结尾「=」之外的字符会被拒绝(可防止头部注入)。
工具
Base64 编码器
将文本或二进制数据编码为 Base64。免费、隐私优先、100% 纯客户端运行。支持 UTF-8、ASCII、Latin1、UTF-16LE 字符集,可处理多语言文本与二进制内容,结果可直接用于 Data URI、邮件附件、JWT 等场景。
工具
Base64 解码器
将 Base64 数据解码为可读文本。免费、隐私优先、100% 纯客户端运行。支持 UTF-8、ASCII、Latin1、UTF-16LE 字符集,可处理 Data URI、JWT 载荷、邮件附件等场景,遇到非法输入会明确报错而非静默产生乱码。
工具
哈希计算器
计算 MD5、SHA-1、SHA-256 或 SHA-512 哈希,支持十六进制或 Base64 输出。免费、隐私、100% 客户端运行。SHA-256/512 基于 Web Crypto API,MD5 基于 spark-md5,适用于校验和、完整性验证、指纹识别等场景。MD5 与 SHA-1 已不适用于安全场景。
工具
SHA-3 / Keccak 哈希计算器
计算 SHA-3(224/256/384/512)和 Keccak-256 哈希。免费、隐私、100% 客户端运行。
工具
随机字节生成器
生成密码学安全的随机字节或整数。免费、隐私优先、100% 纯客户端运行。
工具
URL 编码器
对文本进行百分号编码,以安全地用于 URL。免费、隐私优先、100% 纯客户端运行。支持组件模式(编码所有保留字符)和完整 URL 模式(保留 ://? 等结构),支持 UTF-8/ASCII/Latin1/UTF-16LE 字符集,适合构建查询参数、路径片段和 API 请求。
工具
URL 解码器
将百分号编码的 URL 文本解码为可读字符。免费、隐私优先、100% 纯客户端运行。支持 UTF-8/ASCII/Latin1/UTF-16LE 字符集,遇到截断的百分号或非法十六进制会明确报错,适合解析查询参数、路径片段和 API 响应中的编码内容。
工具

相关词条

参考链接