OAuth 2.1完全ガイド|OAuth 2.0との違い・PKCE必須化と移行チェックリスト
OAuth 2.1草案は、暗黙的フロー廃止やPKCE必須化など安全策を標準化しました。この記事では2.0との違いと移行手順をわかりやすく解説します。
OAuth 2.1草案の背景と目的
OAuth 2.0(RFC 6749/6750, 2012年10月公開)はソーシャルログインやAPI連携の中核技術として普及しましたが、暗黙的フローの脆弱性や拡張仕様を読まなければ安全に実装できない点が課題でした。
複数RFCを横断する負担が増え、開発・運用双方でコストが高まったのです。OAuth 2.1草案(Draft‑13, 2025‑05‑28公開)は、安全策を本体に統合し、高リスク機能を削除してSecure by Defaultを実現します。
WG内のレビューは収束傾向にあるものの IESG Last Call にはまだ未到達で、今後もセクション番号やパラメータ名が微調整される可能性があります。従ってコードに定数やセクション番号をハードコーディングしない設計が望まれます。
OAuth 2.1の主要変更点まとめ
- 安全なデフォルトの必須化 — パブリッククライアントは PKCEがMUST。機密クライアントはPKCE または 同等のコード注入対策(mTLS、DPoP、Token Binding など)をSHOULD採用。
- 危険なフローの削除 — 暗黙的フローとROPCを除外。ユーザ主体のシナリオでは Authorization Code + PKCE がデフォルト推奨だが、Device Authorization Grant・Client Credentials Grant は継続。
- トークン取扱いの厳格化 — アクセストークンの URI クエリ送信を禁止。Form Bodyでの送信は後方互換として残るものの、HTTPS + POST + Content‑Type: application/x-www-form-urlencoded + CSRF防御などすべての条件を満たす場合のみ許容され非推奨。新規実装は
Authorization: Bearer
ヘッダ一択とする。
また、パブリッククライアントではRefresh Token Rotation(ワンタイムやSender‑Constrainedいずれか)がMUST、機密クライアントでは推奨。
さらに code_challenge_method
は S256 サポートが MUST、plain
はサーバ合意時のみ利用可。リダイレクトURIは完全一致(Exact String Match)が必須です。
OAuth 2.0とOAuth 2.1の違い比較表
項目 | OAuth 2.0 | OAuth 2.1草案 |
---|---|---|
PKCE | モバイル向け拡張(任意) | パブリックは必須/機密は PKCE か mTLS・DPoP 等をSHOULD |
暗黙的フロー | 残存(非推奨) | 削除 |
ROPCフロー | 限定的に許容 | 削除 |
Device & Client Credentials | 利用可能 | 継続利用可能 |
Refresh Token | Rotation 任意 | パブリックで必須/機密で推奨(token_type_hint=refresh_token 使用) |
アクセストークン送信 | クエリ送信可/Form Body可 | クエリ送信禁止/Form Bodyは条件付き非推奨/ヘッダ推奨 |
code_challenge_method | 規定なし | S256必須/plainは限定可 |
リダイレクトURI | ワイルドカード容認実装あり | 完全一致必須 |
開発者が押さえるべき重点ポイント
① PKCEの実装code_verifier
は43〜128文字の高エントロピー文字列、code_challenge
はS256がデフォルト。機密クライアントでのPKCE導入はクライアントシークレット漏洩時の保険になります。
② Sender‑Constrainedトークン
DPoP(RFC 9449)、mTLS(RFC 8705)などでトークンをクライアントにバインドし、Refresh Token Rotationを“ワンタイム使用+バインディング”で補強すると高リスクAPIの防御力が向上します。
③ SPA移行
バックチャネルでコードを交換し、CORS・SameSiteクッキーに加え Mix‑Up Attack対策の Issuer Identification(Draft 13 附録 7.10)を採用。DPoPヘッダを送信し、トークン窃取リスクを最小化します。
④ Form Body送信の取り扱い
互換目的で残りますが安全条件は厳格です。
- HTTPS
- HTTP POST
- Content‑Type: application/x-www-form-urlencoded
- CSRF防御(state / origin)
これらを満たしても非推奨。ヘッダ送信へ移行しましょう。
⑤ リダイレクトURIの厳格一致
ワイルドカード登録を廃し、開発環境用は別エントリに明示登録。CIでスキャンし、部分一致設定がないか検証します。
移行チェックリスト
- クライアント種別の棚卸し(Public / Confidential)と PKCE または代替策の適用確認
- client_id を Refresh Token リクエスト時に明示送信しているかチェック
- Implicit / ROPC 呼び出しをログ分析で検出し、代替フローへリライト
- Refresh Token Rotation 実装:
token_type_hint=refresh_token
を使って失効API呼び出し - Sender‑Constrained(DPoP, mTLS)導入計画と証明書/鍵管理フロー策定
- アクセストークン URI クエリ送信テスト(NGケース)をCIに追加
- Form Body送信許可条件(HTTPS, POST など)の自動検査
- リダイレクトURI完全一致設定を静的解析で検証
- Mix‑Up Attack 対策の Issuer ID 検証ロジックを追加
- セクション番号・定数のハードコード禁止、環境変数化
- ライブラリ/SDK の“2.1対応フラグ有無”を調査し、アップグレード計画に明示
FAQ(よくある質問)
- OAuth 2.1はいつ正式RFCになる?
-
Draft‑13時点でWGレビューは落ち着いていますが IESG Last Callには未到達です。破壊的変更は低めとはいえ、エラーパラメータ名やセクション番号の変更は起こり得るため、コード上のハードコーディングは避けましょう。
- nonce は必須?
-
nonce
は OpenID Connect 特有のパラメータで OAuth 2.1 本体には必須要件がありません。OIDC を併用する場合のみ実装してください。 - 機密クライアントでPKCEを採用すべき?
-
必須ではありませんが、mTLS・DPoP と組み合わせた二重防御は有効です。高機密APIでは採用を推奨します。
- Form Body 送信は本当に非推奨?
-
はい。厳格な条件を守っても新規実装では避けるべきです。ヘッダ送信へ移行し、コードレビューで禁止ルールを設定してください。
パスキーとは?FIDO2で始める“本当の”パスワードレス認証徹底ガイド
まとめと次のアクション
OAuth 2.1草案は“安全オプションがデフォルトになる”マイルストーンです。暗黙的フローやROPCの削除、PKCE・Refresh Token Rotation必須化により、攻撃面を大幅に狭めます。
この記事の比較表とチェックリストをタスク化し、CIに組み込んで差分検出を自動化することで、ドラフト更新にも迅速に追随可能です。
ライブラリの2.1対応フラグを確認し、移行ロードマップと予算を確定させましょう。安全で一貫性のあるユーザー体験を提供するため、今こそアップグレードの舵を切るタイミングです。