Secure Steady
認可コードフロー - 認可コードフロー の使い方・オプション・サンプル

認可コードフロー - 認可コードフロー

サーバーサイドアプリ向けの最も安全な OAuth 2.0 フロー。認可コードをバックチャネルでトークンに交換する。

概念図

認可コードフロー diagram

実例

認可リクエスト URL の構築例。state パラメータで CSRF を防止する

bash
GET /authorize?
  response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https://app.example.com/callback
  &scope=read write
  &state=xyz123random

トークンエンドポイントへの POST リクエスト。認可コードをアクセストークンに交換する

bash
POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=AUTH_CODE_FROM_CALLBACK
&redirect_uri=https://app.example.com/callback
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET

state パラメータによる CSRF 対策の実装例

bash
// state パラメータの生成と検証
const state = crypto.randomBytes(32).toString("hex");
req.session.oauthState = state;
// 認可リクエストに state を含める

// コールバック時の検証
if (req.query.state !== req.session.oauthState) {
  throw new Error("State mismatch - possible CSRF attack");
}

フローの全体像

認可コードフローは以下の 4 ステップで構成されます。

  1. 認可リクエスト: クライアントがユーザーを認可サーバーの /authorize エンドポイントにリダイレクトする。response_type=codeclient_idredirect_uriscopestate を含める

  2. 認可コードの発行: ユーザーが同意すると、認可サーバーが redirect_uri に認可コード(code)を付与してリダイレクトする。認可コードは短命(通常 10 分以内)で一回限り有効

  3. トークン交換(バックチャネル): クライアントのサーバーが認可コードと client_secret を使い、認可サーバーの /token エンドポイントに POST リクエストを送信する。この通信はサーバー間(バックチャネル)で行われるため、ブラウザにトークンが露出しない

  4. リソースアクセス: 取得したアクセストークンを Authorization: Bearer ヘッダに含め、リソースサーバーの API にアクセスする

セキュリティ上の注意点

  • state パラメータの検証: 認可リクエスト時にランダムな state 値を生成してセッションに保存し、コールバック時に一致を検証する。これを省略すると CSRF 攻撃により攻撃者のアカウントと紐付けられる危険がある

  • redirect_uri の厳密な固定: 認可サーバーに登録した redirect_uri と完全一致させる。部分一致やワイルドカードを許可すると、オープンリダイレクタ経由で認可コードが漏洩する

  • 認可コードの一回限り使用: 認可コードは一度トークンに交換したら無効化する。再利用が検出された場合は、そのコードで発行済みのトークンもすべて失効させるべき(RFC 6749 Section 4.1.2)

  • client_secret の保護: クライアントシークレットはサーバーサイドのみで保持し、フロントエンドやバージョン管理に含めない。環境変数やシークレットマネージャーで管理する

  • HTTPS の強制: 認可コードやトークンの通信はすべて HTTPS で行う。HTTP での通信は中間者攻撃によるトークン漏洩のリスクがある

関連トピック