コンテンツへスキップ
uencoder

OAuth 2.0 PKCE フローを実装する方法

OAuth 2.0 認可コードフローに Proof Key for Code Exchange(PKCE)拡張を実装し、パブリッククライアントの認証を安全に行います。

问题

SPA やモバイルアプリなどのパブリッククライアントはクライアントシークレットを安全に保持できず、認可コードの傍受攻撃に対して脆弱です。PKCE(RFC 7636)を実装して、認可コードをクライアントのみが知るコードベリファイアに紐付ける必要があります。

前提条件

  • OAuth 2.0 認可コードフローの理解
  • パブリッククライアントとコンフィデンシャルクライアントの違いへの習熟
  • 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 フロー。認可コードの傍受や CSRF 攻撃から保護されます。

よくあるエラー

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 トークンパーサー
Oauth Token Parser — 純クライアントサイドツール。プライバシーファースト、サーバー往復なし。
ツール
JWT デコーダー
Decode and inspect JWT header, payload, and time claims with expiry status。無料、プライベート、100%クライアントサイド。
ツール
JWT エンコーダー
エンコード JWT with HS256. Free, private, 100% client-side. Not for server-side verification.
ツール
Bearer トークンジェネレーター
トークン文字列から「Bearer <token>」Authorization ヘッダー(RFC 6750)を構築します。トークンは b64token 構文で検証され、英数字・-._~+/・末尾の「=」以外の文字は拒否されます(ヘッダーインジェクション防止)。
ツール
Base64 エンコーダー
Encode text or binary data to Base64 online。無料、プライベート、100%クライアントサイド。
ツール
Base64 デコーダー
Decode Base64 data back to readable text online。無料、プライベート、100%クライアントサイド。
ツール
ハッシュ計算ツール
Compute MD5, SHA-1, SHA-256, or SHA-512 hashes with hex or Base64 output。無料、プライベート、100%クライアントサイド。
ツール
SHA-3 / Keccak ハッシュ計算
Compute SHA-3 (224/256/384/512) and Keccak-256 hashes。無料、プライベート、100%クライアントサイド。
ツール
ランダムバイトジェネレーター
Generate cryptographically secure random bytes or integers。無料、プライベート、100%クライアントサイド。
ツール
URL エンコーダー
Percent-encode text for safe use in URLs。無料、プライベート、100%クライアントサイド。
ツール
URL デコーダー
Decode percent-encoded URL text back to readable characters。無料、プライベート、100%クライアントサイド。
ツール

関連用語

参考链接