mcpField
Z
zoom-oauth

zoom-oauth

github.com/anthropicsセキュリティ33.6k2.1k 回インストール1 日前に更新
リポジトリ

zoom-oauth について

Zoom APIの認証を実装する開発者向けのOAuthリファレンススキルです。4種類の認可フロー、スコープ、PKCE、トークンのライフサイクル、トラブルシューティングを解説します。

主な機能

  1. 014種類のOAuth認可フロー
  2. 02トークン交換と更新の案内
  3. 03パブリッククライアント向けPKCE
  4. 04従来型と細粒度スコープ
  5. 05失効と認可解除の案内
  6. 06トラブルシューティングと手順書

活用シーン

  1. 01Zoomアプリの認可フロー選定
  2. 02ユーザーまたはデバイス認可の実装
  3. 03トークン更新と保存の管理
  4. 04OAuthエラーの診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/anthropics/knowledge-work-plugins --skill zoom-oauth

インストール後、Claude Code で/zoom-oauthを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

RUNBOOK.md
concepts/
oauth-flows.md
pkce.md
scopes-architecture.md
state-parameter.md
token-lifecycle.md
examples/
device-flow.md
pkce-implementation.md
s2s-oauth-basic.md
s2s-oauth-redis.md
token-refresh.md
user-oauth-basic.md
user-oauth-mysql.md
references/
classic-scopes.md
environment-variables.md
granular-scopes.md
oauth-errors.md
troubleshooting/
common-errors.md
redirect-uri-issues.md
scope-issues.md
token-issues.md

詳細

Zoom OAuth

Zoom の認証とトークンのライフサイクル動作に関する背景資料です。まず setup-zoom-oauth を使用し、その後、正確なフロー、スコープ、エラーの詳細についてこのスキルを使用してください。

Zoom OAuth

Zoom API の認証と認可。

📖 完全なドキュメント

包括的なガイド、本番環境でのパターン、トラブルシューティングについては、以下の統合インデックスのセクションを参照してください。

クイックナビゲーション:

前提条件

  • Marketplace で作成した Zoom アプリ
  • Client ID と Client Secret
  • S2S OAuth の場合:Account ID

4 つの認可ユースケース

ユースケースアプリの種類Grant Type業界での名称
アカウント認可Server-to-Serveraccount_credentialsClient Credentials Grant、M2M、Two-legged OAuth
ユーザー認可Generalauthorization_codeAuthorization Code Grant、Three-legged OAuth
デバイス認可Generalurn:ietf:params:oauth:grant-type:device_codeDevice Authorization Grant(RFC 8628)
クライアント認可Generalclient_credentialsClient Credentials Grant(チャットボットスコープ)
業界用語
用語意味
Two-legged OAuthユーザーは関与しません(クライアント ↔ サーバー)
Three-legged OAuthユーザーが関与します(ユーザー ↔ クライアント ↔ サーバー)
M2MMachine-to-Machine(バックエンドサービス)
パブリッククライアントシークレットを保持できません(モバイル、SPA)→ PKCE を使用します
コンフィデンシャルクライアントシークレットを保持できます(バックエンドサーバー)
PKCEProof Key for Code Exchange(RFC 7636)、発音は「ピクシー」です
どのフローを使用すればよいですか?
                              ┌─────────────────────┐
                              │  What are you       │
                              │  building?          │
                              └──────────┬──────────┘
                                         │
                    ┌────────────────────┼────────────────────┐
                    │                    │                    │
                    ▼                    ▼                    ▼
          ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
          │  Backend        │  │  App for other  │  │  Chatbot only   │
          │  automation     │  │  users/accounts │  │  (Team Chat)    │
          │  (your account) │  │                 │  │                 │
          └────────┬────────┘  └────────┬────────┘  └────────┬────────┘
                   │                    │                    │
                   ▼                    │                    ▼
          ┌─────────────────┐           │           ┌─────────────────┐
          │    ACCOUNT      │           │           │     CLIENT      │
          │   (S2S OAuth)   │           │           │   (Chatbot)     │
          └─────────────────┘           │           └─────────────────┘
                                        │
                                        ▼
                              ┌─────────────────────┐
                              │  Does device have   │
                              │  a browser?         │
                              └──────────┬──────────┘
                                         │
                         ┌───────────────┴───────────────┐
                         │ NO                         YES│
                         ▼                               ▼
          ┌─────────────────────────┐         ┌─────────────────┐
          │        DEVICE           │         │      USER       │
          │     (Device Flow)       │         │  (Auth Code)    │
          │                         │         │                 │
          │ Examples:               │         │ + PKCE if       │
          │ • Smart TV              │         │   public client │
          │ • Meeting SDK device    │         │                 │
          └─────────────────────────┘         └─────────────────┘

アカウント認可(Server-to-Server OAuth)

ユーザーの操作を必要としないバックエンドの自動化向けです。

アクセストークンをリクエストする
POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={ACCOUNT_ID}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
レスポンス
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "user:read:user:admin",
  "api_url": "https://api.zoom.us"
}
更新

アクセストークンの有効期限は 1 時間です。個別の更新フローはありません。新しいトークンをリクエストしてください。


ユーザー認可(Authorization Code Flow)

ユーザーに代わって動作するアプリ向けです。

ステップ 1:ユーザーを認可画面にリダイレクトする
https://zoom.us/oauth/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}

同意には https://zoom.us/oauth/authorize を使用しますが、トークン交換には https://zoom.us/oauth/token を使用します。

任意のパラメーター:

パラメーター説明
stateCSRF 保護。フロー全体で状態を維持します
code_challengePKCE 用(以下を参照)
code_challenge_methodS256 または plain(デフォルト:plain)
ステップ 2:ユーザーが認可する
  • ユーザーがサインインして、権限を付与します
  • redirect_uri に認可コードを付けてリダイレクトします:
    https://example.com/?code={AUTHORIZATION_CODE}
    
ステップ 3:コードをトークンに交換する
POST https://zoom.us/oauth/token?grant_type=authorization_code&code={CODE}&redirect_uri={REDIRECT_URI}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}

PKCE を使用する場合: code_verifier パラメーターを追加します。

レスポンス
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "refresh_token": "eyJ...",
  "expires_in": 3600,
  "scope": "user:read:user",
  "api_url": "https://api.zoom.us"
}
リフレッシュトークン
POST https://zoom.us/oauth/token?grant_type=refresh_token&refresh_token={REFRESH_TOKEN}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
  • アクセストークンの有効期限は 1 時間です
  • リフレッシュトークンの有効期間は変動します。一部のユーザーベースのフローでは約 90 日が一般的です。設定や動作は変更される可能性があるものとして扱い、実行時のエラーと再認証へのフォールバックに依存してください。
  • 次のリクエストでは、必ず最新のリフレッシュトークンを使用してください
  • リフレッシュトークンの有効期限が切れた場合は、認可 URL にユーザーをリダイレクトしてフローを再開してください
ユーザーレベルアプリとアカウントレベルアプリ
種類認可できるユーザースコープへのアクセス
ユーザーレベル任意の個人ユーザー自分自身に限定
アカウントレベル管理者権限を持つユーザーアカウント全体へのアクセス(管理者スコープ)

デバイス認可(デバイスフロー)

ブラウザーを利用できないデバイス向けです(Meeting SDK アプリなど)。

前提条件

Features > Embed で「Use App on Device」を有効にします:Enable Meeting SDK

ステップ 1:デバイスコードをリクエストする
POST https://zoom.us/oauth/devicecode?client_id={CLIENT_ID}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
レスポンス
{
  "device_code": "DEVICE_CODE",
  "user_code": "abcd1234",
  "verification_uri": "https://zoom.us/oauth_device",
  "verification_uri_complete": "https://zoom.us/oauth/device/complete/{CODE}",
  "expires_in": 900,
  "interval": 5
}
ステップ 2:ユーザーによる認証

ユーザーに次のいずれかを案内します。

  • verification_uri にアクセスし、user_code を手動で入力する
  • verification_uri_complete にアクセスする(ユーザーコードは入力済み)

ユーザーがサインインし、アプリを許可します。

ステップ 3:トークンのポーリング

ユーザーが認証するまで、interval(5 秒)ごとにポーリングします。

POST https://zoom.us/oauth/token?grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code={DEVICE_CODE}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
レスポンス
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "refresh_token": "eyJ...",
  "expires_in": 3599,
  "scope": "user:read:user user:read:token",
  "api_url": "https://api.zoom.us"
}
ポーリングのレスポンス
レスポンス意味対応
トークンが返されるユーザーが認証したトークンを保存して完了
error: authorization_pendingユーザーはまだ認証していない間隔ごとにポーリングを続ける
error: slow_downポーリングが速すぎる間隔を 5 秒増やす
error: expired_tokenデバイスコードの有効期限が切れた(15 分)ステップ 1 からフローを再開する
error: access_deniedユーザーが認証を拒否した拒否を処理し、再試行しない
ポーリングの実装
async function pollForToken(deviceCode, interval) {
  while (true) {
    await sleep(interval * 1000);
    
    try {
      const response = await axios.post(
        `https://zoom.us/oauth/token?grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=${deviceCode}`,
        null,
        { headers: { 'Authorization': `Basic ${credentials}` } }
      );
      return response.data; // Success - got tokens
    } catch (error) {
      const err = error.response?.data?.error;
      if (err === 'authorization_pending') continue;
      if (err === 'slow_down') { interval += 5; continue; }
      throw error; // expired_token or access_denied
    }
  }
}
更新

ユーザー認証と同じです。リフレッシュトークンの有効期限が切れた場合は、ステップ 1 からデバイスフローを再開します。


クライアント認証(チャットボット)

チャットボットのメッセージ操作専用です。

トークンのリクエスト
POST https://zoom.us/oauth/token?grant_type=client_credentials

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
レスポンス
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "imchat:bot",
  "api_url": "https://api.zoom.us"
}
更新

トークンの有効期限は 1 時間 です。更新フローはありません。新しいトークンをリクエストしてください。


アクセストークンの使用

API の呼び出し
GET https://api.zoom.us/v2/users/me

Headers:
Authorization: Bearer {ACCESS_TOKEN}
Me コンテキスト

userID を me に置き換えると、トークンに関連付けられたユーザーを対象にできます。

エンドポイントメソッド
/v2/users/meGET, PATCH
/v2/users/me/tokenGET
/v2/users/me/meetingsGET, POST

アクセストークンの取り消し

すべての認証タイプで使用できます。

POST https://zoom.us/oauth/revoke?token={ACCESS_TOKEN}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
レスポンス
{
  "status": "success"
}

PKCE(Proof Key for Code Exchange)

シークレットを安全に保存できないパブリッククライアント(モバイルアプリ、SPA、デスクトップアプリ)向けです。

PKCE を使用する場面
クライアントの種類PKCE を使用するか理由
モバイルアプリはいクライアントシークレットを安全に保存できない
シングルページアプリ(SPA)はいJavaScript がユーザーに見える
デスクトップアプリはいバイナリを逆コンパイルできる
Meeting SDK(クライアント側)はいユーザーのデバイス上で実行される
バックエンドサーバー任意シークレットを保持できますが、PKCE によってセキュリティが向上する
PKCE の仕組み
┌──────────┐                              ┌──────────┐                    ┌──────────┐
│  Client  │                              │   Zoom   │                    │   Zoom   │
│   App    │                              │  Auth    │                    │  Token   │
└────┬─────┘                              └────┬─────┘                    └────┬─────┘
     │                                         │                              │
     │ 1. Generate code_verifier (random)      │                              │
     │ 2. Create code_challenge = SHA256(verifier)                            │
     │                                         │                              │
     │ ─────── /authorize + code_challenge ──► │                              │
     │                                         │                              │
     │ ◄────── authorization_code ──────────── │                              │
     │                                         │                              │
     │ ─────────────── /token + code_verifier ─┼────────────────────────────► │
     │                                         │                              │
     │                                         │     Verify: SHA256(verifier) │
     │                                         │            == challenge      │
     │                                         │                              │
     │ ◄───────────────────────────────────────┼─────── access_token ──────── │
     │                                         │                              │
実装(Node.js)
const crypto = require('crypto');

function generatePKCE() {
  const verifier = crypto.randomBytes(32).toString('base64url');
  const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');
  return { verifier, challenge };
}

const pkce = generatePKCE();

const authUrl = `https://zoom.us/oauth/authorize?` +
  `response_type=code&` +
  `client_id=${CLIENT_ID}&` +
  `redirect_uri=${REDIRECT_URI}&` +
  `code_challenge=${pkce.challenge}&` +
  `code_challenge_method=S256`;

// Store pkce.verifier in session for callback
PKCE を使用したトークン交換
POST https://zoom.us/oauth/token?grant_type=authorization_code&code={CODE}&redirect_uri={REDIRECT_URI}&code_verifier={VERIFIER}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}

認証解除

ユーザーがアプリを削除すると、Zoom から認証解除通知エンドポイントの URL に Webhook が送信されます。

Webhook イベント
{
  "event": "app_deauthorized",
  "event_ts": 1740439732278,
  "payload": {
    "account_id": "ACCOUNT_ID",
    "user_id": "USER_ID",
    "signature": "SIGNATURE",
    "deauthorization_time": "2019-06-17T13:52:28.632Z",
    "client_id": "CLIENT_ID"
  }
}
要件
  • このイベントを受信した後、関連するすべてのユーザーデータを削除する
  • Webhook の署名を検証する(シークレットトークンを使用してください。検証トークンは 2023 年 10 月に非推奨になりました)
  • 認証解除の Webhook を受信するのはパブリックアプリのみです(プライベートアプリや開発用アプリは対象外)

事前承認フロー

一部の Zoom アカウントでは、ユーザーがアプリを認証する前に Marketplace 管理者による事前承認が必要です。

  • ユーザーは管理者に事前承認を申請できます
  • アカウントレベルのアプリ(管理者スコープ)には、適切なロール権限が必要です

Active Apps Notifier(AAN)

コンテンツにリアルタイムでアクセスしているアプリを会議中に表示する機能です。

  • アプリの情報、アクセス中のコンテンツの種類、承認したアカウントをアイコンとツールチップで表示します
  • 対応バージョン:Zoom クライアント 5.6.7 以降、Meeting SDK 5.9.0 以降

OAuth スコープ

スコープの種類
種類説明対象
従来のスコープ旧式のスコープ(ユーザー、管理者、マスターレベル)既存のアプリ
詳細なスコープオプションのサポートを備えた、新しい細分化されたスコープ新しいアプリ
従来のスコープ

以前に作成されたアプリ向けです。次の 3 つのレベルがあります。

  • ユーザーレベル:個々のユーザーのデータへのアクセス
  • 管理者レベル:アカウント全体へのアクセス。管理者ロールが必要
  • マスターレベル:マスター/サブアカウント構成向け。アカウントオーナーが必要

一覧:https://developers.zoom.us/docs/integrations/oauth-scopes/

詳細なスコープ

新しいアプリ向けです。形式:<service>:<action>:<data_claim>:<access>

コンポーネント値
servicemeeting、webinar、user、recording など
actionread、write、update、delete
data_claimデータのカテゴリ(例:participants、settings)
access空(ユーザー)、admin、master

例:meeting:read:list_meetings:admin

全一覧:https://developers.zoom.us/docs/integrations/oauth-scopes-granular/

オプションのスコープ

詳細なスコープはオプションとして指定でき、ユーザーが付与するかどうかを選択できます。

基本認証(ビルドフローのデフォルトを使用):

https://zoom.us/oauth/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}

高度な認証(リクエストごとにカスタムスコープを指定):

https://zoom.us/oauth/authorize?client_id={CLIENT_ID}&response_type=code&redirect_uri={REDIRECT_URI}&scope={required_scopes}&optional_scope={optional_scopes}

以前に付与されたスコープを含める:

https://zoom.us/oauth/authorize?...&include_granted_scopes&scope={additional_scopes}
クラシックから詳細なスコープへの移行
  1. Manage > アプリを選択 > 編集
  2. Scope ページ > Development タブ > Migrateをクリック
  3. 自動割り当てされた詳細なスコープを確認し、不要なものを削除して、オプションとして指定
  4. テスト
  5. Production タブ > Migrateをクリック

注意:

  • スコープの移行または削減のみの場合、レビューは不要です
  • 既存のユーザートークンは、再認証するまでクラシックスコープの値を引き続き使用します
  • 移行後、新規ユーザーには詳細なスコープが付与されます

一般的なエラーコード

コードメッセージ解決策
4700トークンを空にすることはできませんAuthorization ヘッダーに有効なトークンがあることを確認してください
4702/4704クライアントが無効ですClient ID と Client Secret を確認してください
4705グラントタイプがサポートされていませんaccount_credentials、authorization_code、urn:ietf:params:oauth:grant-type:device_code、または client_credentials を使用してください
4706Client ID またはシークレットがありませんヘッダーまたはリクエストパラメーターに認証情報を追加してください
4709リダイレクト URI が一致しませんredirect_uri がアプリの設定と完全に一致することを確認してください(末尾のスラッシュを含む)
4711リフレッシュトークンが無効ですトークンのスコープがクライアントのスコープと一致していません
4717アプリが無効化されていますZoom サポートにお問い合わせください
4733コードの有効期限が切れています認証コードの有効期限は5分です。フローを再開してください
4734認証コードが無効です認証コードを再生成してください
4735トークンの所有者が存在しませんユーザーがアカウントから削除されています。再認証してください
4741トークンが取り消されています最新の認証で発行された最新のトークンを使用してください

エラーの完全な一覧は references/oauth-errors.md を参照してください。


クイックリファレンス

フローグラントタイプトークンの有効期限更新
アカウント(S2S)account_credentials1時間新しいトークンをリクエスト
ユーザーauthorization_code1時間refresh_token を使用(有効期限90日)
デバイスurn:ietf:params:oauth:grant-type:device_code1時間refresh_token を使用(有効期限90日)
クライアント(チャットボット)client_credentials1時間新しいトークンをリクエスト

デモのガイダンス

OAuth デモアプリを作成する場合、その実行時のベース URL は、この共有スキルではなく、デモプロジェクト独自の README または .env.example に記載してください。

リソース


統合インデックス

このセクションは SKILL.md から移行されました。

クイックスタートガイド

Zoom OAuth を初めて利用する場合は、次の順に進めてください。

  1. まず事前チェックを実行する → RUNBOOK.md

  2. OAuth フローを選ぶ → concepts/oauth-flows.md

    • 4 つのフロー:S2S(バックエンド)、User(SaaS)、Device(ブラウザーなし)、Chatbot
    • 選択マトリックス:どのフローがユースケースに適していますか?
  3. トークンのライフサイクルを理解する → concepts/token-lifecycle.md

    • 重要:トークンの有効期限、更新、取り消しについて
    • よくある落とし穴:リフレッシュトークンのローテーション
  4. フローを実装する → サンプルに進みます:

  5. リダイレクト URI の問題を解決する → troubleshooting/redirect-uri-issues.md

    • 最もよくある OAuth エラー:リダイレクト URI の不一致
  6. トークンの更新を実装する → examples/token-refresh.md

    • 自動ミドルウェアのパターン
    • リフレッシュトークンのローテーションへの対応
  7. エラーをトラブルシューティングする → troubleshooting/common-errors.md

    • エラーコードの表(4700~4741 の範囲)
    • 簡易診断ワークフロー

ドキュメントの構成

oauth/
├── SKILL.md                           # Main skill overview
├── SKILL.md                           # This file - navigation guide
│
├── concepts/                          # Core OAuth concepts
│   ├── oauth-flows.md                # 4 flows: S2S, User, Device, Chatbot
│   ├── token-lifecycle.md            # Expiration, refresh, revocation
│   ├── pkce.md                       # PKCE security for public clients
│   ├── scopes-architecture.md        # Classic vs Granular scopes
│   └── state-parameter.md            # CSRF protection with state
│
├── examples/                          # Complete working code
│   ├── s2s-oauth-basic.md            # S2S OAuth minimal example
│   ├── s2s-oauth-redis.md            # S2S OAuth with Redis caching (production)
│   ├── user-oauth-basic.md           # User OAuth minimal example
│   ├── user-oauth-mysql.md           # User OAuth with MySQL + encryption (production)
│   ├── device-flow.md                # Device authorization flow
│   ├── pkce-implementation.md        # PKCE for SPAs/mobile apps
│   └── token-refresh.md              # Auto-refresh middleware pattern
│
├── troubleshooting/                   # Problem solving guides
│   ├── common-errors.md              # Error codes 4700-4741
│   ├── redirect-uri-issues.md        # Most common OAuth error
│   ├── token-issues.md               # Expired, revoked, invalid tokens
│   └── scope-issues.md               # Scope mismatch errors
│
└── references/                        # Reference documentation
    ├── oauth-errors.md                # Complete error code reference
    ├── classic-scopes.md              # Classic scope reference
    └── granular-scopes.md             # Granular scope reference

ユースケース別

自分のアカウントで Zoom のタスクを自動化したい
  1. OAuth Flows - S2S OAuth の解説
  2. S2S OAuth Redis - Redis キャッシュを使った本番環境向けパターン
  3. Token Lifecycle - 1 時間有効のトークン、更新なし
他の Zoom ユーザー向けの SaaS アプリを構築したい
  1. OAuth Flows - User OAuth の解説
  2. User OAuth MySQL - 暗号化を使った本番環境向けパターン
  3. Token Refresh - 自動更新ミドルウェア
  4. Redirect URI Issues - 最もよくあるエラーを解決
モバイルアプリまたは SPA を構築したい
  1. PKCE - パブリッククライアントに PKCE が必要な理由
  2. PKCE Implementation - 完全なコード例
  3. State Parameter - CSRF 対策
ブラウザーのないデバイス(TV、キオスク)向けのアプリを構築したい
  1. OAuth Flows - Device フローの解説
  2. Device Flow Example - ポーリングの完全な実装
  3. Common Errors - Device 固有のエラー
Team Chat ボットを構築している
  1. OAuth Flows - Chatbot フローの解説
  2. S2S OAuth Basic - 類似のパターン、異なるグラントタイプ
  3. Scopes Architecture - Chatbot 固有のスコープ
リダイレクト URI エラー(4709)が発生する
  1. Redirect URI Issues - まずはこちら!
  2. Common Errors - エラーの詳細
  3. User OAuth Basic - 正しいパターンを確認
トークンエラー(4700~4741)が発生する
  1. Token Issues - 診断ワークフロー
  2. Token Lifecycle - 有効期限について理解する
  3. Token Refresh - 自動更新を実装する
  4. Common Errors - エラーコードの表
スコープエラーが発生します(4711)
  1. スコープの問題 - 不一致の原因
  2. スコープのアーキテクチャ - Classic と Granular の違い
  3. Classic スコープ - スコープの完全なリファレンス
  4. Granular スコープ - Granular スコープのリファレンス
トークンを更新する必要があります
  1. トークンのライフサイクル - 更新するタイミング
  2. トークンの更新 - ミドルウェアのパターン
  3. トークンの問題 - よくある間違い
Classic スコープと Granular スコープの違いを理解したい
  1. スコープのアーキテクチャ - 詳細な比較
  2. Classic スコープ - resource:level 形式
  3. Granular スコープ - service:action:data_claim:access 形式
OAuth の実装をセキュアにしたい
  1. PKCE - パブリッククライアントのセキュリティ
  2. State パラメーター - CSRF 保護
  3. ユーザー OAuth MySQL - 保存時のトークン暗号化
JWT アプリから S2S OAuth に移行したい
  1. S2S OAuth Redis - 最新の代替手段
  2. トークンのライフサイクル - トークンの動作の違い

注:JWT App Type は 2023 年 6 月に非推奨になりました。サーバー間の自動化には S2S OAuth に移行してください。


最も重要なドキュメント

1. OAuth フロー(選択に関するドキュメント)

concepts/oauth-flows.md

4 つのフローのうち、どれを使うべきかを理解します。

  • S2S OAuth:バックエンドの自動化(自分のアカウント)
  • User OAuth:SaaS アプリ(ユーザーがアクセスを許可)
  • Device Flow:ブラウザーのないデバイス
  • Chatbot:Team Chat ボット専用
2. トークンのライフサイクル(最もよくある問題)

concepts/token-lifecycle.md

OAuth の問題の 99% は、次の点への理解不足が原因です。

  • トークンの有効期限(すべてのフローで 1 時間)
  • リフレッシュトークンのローテーション(新しいリフレッシュトークンを保存する必要があります)
  • 失効時の動作(すべてのトークンが無効になります)
3. リダイレクト URI の問題(最もよくあるエラー)

troubleshooting/redirect-uri-issues.md

エラー 4709(「リダイレクト URI の不一致」)は、最もよくある OAuth エラーです。 末尾のスラッシュや http と https の違いも含め、完全に一致させる必要があります。


主な学び

重要な発見:
  1. リフレッシュトークンのローテーション

    • リフレッシュのたびに、新しいリフレッシュトークンが返されます
    • 古いリフレッシュトークンは無効になります
    • 新しいトークンを保存できないと、4735 エラーが発生します
    • 参照:トークンのリフレッシュ
  2. S2S OAuth では Redis、ユーザー OAuth ではデータベースを使用

  3. リダイレクト URI は完全に一致する必要があります

    • 末尾のスラッシュが重要です:/callback ≠ /callback/
    • プロトコルが重要です:http:// ≠ https://
    • ポートが重要です::3000 ≠ :3001
    • 参照:リダイレクト URI の問題
  4. パブリッククライアントには PKCE が必要です

    • モバイルアプリではシークレットを保持できません
    • SPA ではシークレットを保持できません
    • PKCE は認可コードの傍受を防ぎます
    • 参照:PKCE
  5. State パラメーターは CSRF を防ぎます

    • リダイレクトの前にランダムな state を生成します
    • セッションに保存します
    • コールバック時に検証します
    • 参照:State パラメーター
  6. トークンの保存時には暗号化が必要です

    • トークンを平文で保存しないでください
    • 最低でも AES-256 を使用してください
    • 参照:ユーザー OAuth と MySQL
  7. JWT アプリタイプは非推奨です(2023 年 6 月)

    • 新しい JWT アプリは作成できません
    • 既存のアプリは引き続き動作しますが、将来的にサポートが終了します
    • S2S OAuth またはユーザー OAuth に移行してください
  8. スコープレベルによって認可要件が決まります

    • 接尾辞なし(ユーザーレベル):どのユーザーでも認可できます
    • :admin:管理者ロールが必要です
    • :master:アカウント所有者が必要です(複数アカウントの場合)
    • 参照:スコープのアーキテクチャ
  9. 認可コードの有効期限は 5 分です

  10. デバイスフローではポーリングが必要です

    • /devicecode が返す間隔(通常は 5 秒)でポーリングしてください
    • authorization_pending、slow_down、expired_token を処理してください
    • 参照:デバイスフロー

クイックリファレンス

「どの OAuth フローを使えばよいですか?」

→ OAuth フロー

「リダイレクト URI 不一致エラー(4709)」

→ リダイレクト URI の問題

「トークンの有効期限が切れた、または無効です」

→ トークンの問題

「リフレッシュトークンが無効です(4735)」

→ トークンのリフレッシュ - 新しいリフレッシュトークンを保存する必要があります

「スコープ不一致エラー(4711)」

→ スコープの問題

「OAuth アプリを保護するにはどうすればよいですか?」

→ PKCE + State パラメーター

「自動リフレッシュを実装するにはどうすればよいですか?」

→ トークンのリフレッシュ

「Classic スコープと Granular スコープの違いは何ですか?」

→ スコープのアーキテクチャ

「エラーコードの意味を知りたい」

→ 一般的なエラー


ドキュメントのバージョン

Zoom OAuth API v2(2024 年以降)に基づいています

非推奨: JWT アプリタイプ(2023 年 6 月)


コーディングをお楽しみください!

どのフローが用途に合っているかを理解するには、OAuth フローから始めてください!

環境変数

コメント