zoom-oauth について
Zoom APIの認証を実装する開発者向けのOAuthリファレンススキルです。4種類の認可フロー、スコープ、PKCE、トークンのライフサイクル、トラブルシューティングを解説します。
主な機能
- 014種類のOAuth認可フロー
- 02トークン交換と更新の案内
- 03パブリッククライアント向けPKCE
- 04従来型と細粒度スコープ
- 05失効と認可解除の案内
- 06トラブルシューティングと手順書
活用シーン
- 01Zoomアプリの認可フロー選定
- 02ユーザーまたはデバイス認可の実装
- 03トークン更新と保存の管理
- 04OAuthエラーの診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ anthropics/ knowledge-work-plugins --skill zoom-oauthインストール後、Claude Code で/zoom-oauthを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
RUNBOOK.mdconcepts/oauth-flows.mdpkce.mdscopes-architecture.mdstate-parameter.mdtoken-lifecycle.mdexamples/device-flow.mdpkce-implementation.mds2s-oauth-basic.mds2s-oauth-redis.mdtoken-refresh.mduser-oauth-basic.mduser-oauth-mysql.mdreferences/classic-scopes.mdenvironment-variables.mdgranular-scopes.mdoauth-errors.mdtroubleshooting/common-errors.mdredirect-uri-issues.mdscope-issues.mdtoken-issues.md詳細
Zoom OAuth
Zoom の認証とトークンのライフサイクル動作に関する背景資料です。まず setup-zoom-oauth を使用し、その後、正確なフロー、スコープ、エラーの詳細についてこのスキルを使用してください。
Zoom OAuth
Zoom API の認証と認可。
📖 完全なドキュメント
包括的なガイド、本番環境でのパターン、トラブルシューティングについては、以下の統合インデックスのセクションを参照してください。
クイックナビゲーション:
- 5 分間のランブック - 詳細なデバッグを始める前の事前チェック
- OAuth フロー - 使用するフローと各フローの仕組み
- トークンのライフサイクル - 有効期限、更新、失効
- 本番環境の例 - Redis キャッシュ、MySQL ストレージ、自動更新
- トラブルシューティング - エラーコード 4700~4741
前提条件
- Marketplace で作成した Zoom アプリ
- Client ID と Client Secret
- S2S OAuth の場合:Account ID
4 つの認可ユースケース
| ユースケース | アプリの種類 | Grant Type | 業界での名称 |
|---|---|---|---|
| アカウント認可 | Server-to-Server | account_credentials | Client Credentials Grant、M2M、Two-legged OAuth |
| ユーザー認可 | General | authorization_code | Authorization Code Grant、Three-legged OAuth |
| デバイス認可 | General | urn:ietf:params:oauth:grant-type:device_code | Device Authorization Grant(RFC 8628) |
| クライアント認可 | General | client_credentials | Client Credentials Grant(チャットボットスコープ) |
業界用語
| 用語 | 意味 |
|---|---|
| Two-legged OAuth | ユーザーは関与しません(クライアント ↔ サーバー) |
| Three-legged OAuth | ユーザーが関与します(ユーザー ↔ クライアント ↔ サーバー) |
| M2M | Machine-to-Machine(バックエンドサービス) |
| パブリッククライアント | シークレットを保持できません(モバイル、SPA)→ PKCE を使用します |
| コンフィデンシャルクライアント | シークレットを保持できます(バックエンドサーバー) |
| PKCE | Proof 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 を使用します。
任意のパラメーター:
| パラメーター | 説明 |
|---|---|
state | CSRF 保護。フロー全体で状態を維持します |
code_challenge | PKCE 用(以下を参照) |
code_challenge_method | S256 または 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/me | GET, PATCH |
/v2/users/me/token | GET |
/v2/users/me/meetings | GET, 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>
| コンポーネント | 値 |
|---|---|
| service | meeting、webinar、user、recording など |
| action | read、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}
クラシックから詳細なスコープへの移行
- Manage > アプリを選択 > 編集
- Scope ページ > Development タブ > Migrateをクリック
- 自動割り当てされた詳細なスコープを確認し、不要なものを削除して、オプションとして指定
- テスト
- 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 を使用してください |
| 4706 | Client ID またはシークレットがありません | ヘッダーまたはリクエストパラメーターに認証情報を追加してください |
| 4709 | リダイレクト URI が一致しません | redirect_uri がアプリの設定と完全に一致することを確認してください(末尾のスラッシュを含む) |
| 4711 | リフレッシュトークンが無効です | トークンのスコープがクライアントのスコープと一致していません |
| 4717 | アプリが無効化されています | Zoom サポートにお問い合わせください |
| 4733 | コードの有効期限が切れています | 認証コードの有効期限は5分です。フローを再開してください |
| 4734 | 認証コードが無効です | 認証コードを再生成してください |
| 4735 | トークンの所有者が存在しません | ユーザーがアカウントから削除されています。再認証してください |
| 4741 | トークンが取り消されています | 最新の認証で発行された最新のトークンを使用してください |
エラーの完全な一覧は references/oauth-errors.md を参照してください。
クイックリファレンス
| フロー | グラントタイプ | トークンの有効期限 | 更新 |
|---|---|---|---|
| アカウント(S2S) | account_credentials | 1時間 | 新しいトークンをリクエスト |
| ユーザー | authorization_code | 1時間 | refresh_token を使用(有効期限90日) |
| デバイス | urn:ietf:params:oauth:grant-type:device_code | 1時間 | refresh_token を使用(有効期限90日) |
| クライアント(チャットボット) | client_credentials | 1時間 | 新しいトークンをリクエスト |
デモのガイダンス
OAuth デモアプリを作成する場合、その実行時のベース URL は、この共有スキルではなく、デモプロジェクト独自の README または .env.example に記載してください。
リソース
- OAuth ドキュメント:https://developers.zoom.us/docs/integrations/oauth/
- S2S OAuth ドキュメント:https://developers.zoom.us/docs/internal-apps/s2s-oauth/
- PKCE ブログ:https://developers.zoom.us/blog/pcke-oauth-with-postman-rest-api/
- クラシックスコープ:https://developers.zoom.us/docs/integrations/oauth-scopes/
- 詳細なスコープ:https://developers.zoom.us/docs/integrations/oauth-scopes-granular/
統合インデックス
このセクションは SKILL.md から移行されました。
クイックスタートガイド
Zoom OAuth を初めて利用する場合は、次の順に進めてください。
-
まず事前チェックを実行する → RUNBOOK.md
-
OAuth フローを選ぶ → concepts/oauth-flows.md
- 4 つのフロー:S2S(バックエンド)、User(SaaS)、Device(ブラウザーなし)、Chatbot
- 選択マトリックス:どのフローがユースケースに適していますか?
-
トークンのライフサイクルを理解する → concepts/token-lifecycle.md
- 重要:トークンの有効期限、更新、取り消しについて
- よくある落とし穴:リフレッシュトークンのローテーション
-
フローを実装する → サンプルに進みます:
- バックエンドの自動化 → examples/s2s-oauth-redis.md
- SaaS アプリ → examples/user-oauth-mysql.md
- モバイル/SPA → examples/pkce-implementation.md
- Device(TV/キオスク) → examples/device-flow.md
-
リダイレクト URI の問題を解決する → troubleshooting/redirect-uri-issues.md
- 最もよくある OAuth エラー:リダイレクト URI の不一致
-
トークンの更新を実装する → examples/token-refresh.md
- 自動ミドルウェアのパターン
- リフレッシュトークンのローテーションへの対応
-
エラーをトラブルシューティングする → 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 のタスクを自動化したい
- OAuth Flows - S2S OAuth の解説
- S2S OAuth Redis - Redis キャッシュを使った本番環境向けパターン
- Token Lifecycle - 1 時間有効のトークン、更新なし
他の Zoom ユーザー向けの SaaS アプリを構築したい
- OAuth Flows - User OAuth の解説
- User OAuth MySQL - 暗号化を使った本番環境向けパターン
- Token Refresh - 自動更新ミドルウェア
- Redirect URI Issues - 最もよくあるエラーを解決
モバイルアプリまたは SPA を構築したい
- PKCE - パブリッククライアントに PKCE が必要な理由
- PKCE Implementation - 完全なコード例
- State Parameter - CSRF 対策
ブラウザーのないデバイス(TV、キオスク)向けのアプリを構築したい
- OAuth Flows - Device フローの解説
- Device Flow Example - ポーリングの完全な実装
- Common Errors - Device 固有のエラー
Team Chat ボットを構築している
- OAuth Flows - Chatbot フローの解説
- S2S OAuth Basic - 類似のパターン、異なるグラントタイプ
- Scopes Architecture - Chatbot 固有のスコープ
リダイレクト URI エラー(4709)が発生する
- Redirect URI Issues - まずはこちら!
- Common Errors - エラーの詳細
- User OAuth Basic - 正しいパターンを確認
トークンエラー(4700~4741)が発生する
- Token Issues - 診断ワークフロー
- Token Lifecycle - 有効期限について理解する
- Token Refresh - 自動更新を実装する
- Common Errors - エラーコードの表
スコープエラーが発生します(4711)
- スコープの問題 - 不一致の原因
- スコープのアーキテクチャ - Classic と Granular の違い
- Classic スコープ - スコープの完全なリファレンス
- Granular スコープ - Granular スコープのリファレンス
トークンを更新する必要があります
- トークンのライフサイクル - 更新するタイミング
- トークンの更新 - ミドルウェアのパターン
- トークンの問題 - よくある間違い
Classic スコープと Granular スコープの違いを理解したい
- スコープのアーキテクチャ - 詳細な比較
- Classic スコープ -
resource:level形式 - Granular スコープ -
service:action:data_claim:access形式
OAuth の実装をセキュアにしたい
- PKCE - パブリッククライアントのセキュリティ
- State パラメーター - CSRF 保護
- ユーザー OAuth MySQL - 保存時のトークン暗号化
JWT アプリから S2S OAuth に移行したい
- S2S OAuth Redis - 最新の代替手段
- トークンのライフサイクル - トークンの動作の違い
注:JWT App Type は 2023 年 6 月に非推奨になりました。サーバー間の自動化には S2S OAuth に移行してください。
最も重要なドキュメント
1. OAuth フロー(選択に関するドキュメント)
4 つのフローのうち、どれを使うべきかを理解します。
- S2S OAuth:バックエンドの自動化(自分のアカウント)
- User OAuth:SaaS アプリ(ユーザーがアクセスを許可)
- Device Flow:ブラウザーのないデバイス
- Chatbot:Team Chat ボット専用
2. トークンのライフサイクル(最もよくある問題)
OAuth の問題の 99% は、次の点への理解不足が原因です。
- トークンの有効期限(すべてのフローで 1 時間)
- リフレッシュトークンのローテーション(新しいリフレッシュトークンを保存する必要があります)
- 失効時の動作(すべてのトークンが無効になります)
3. リダイレクト URI の問題(最もよくあるエラー)
troubleshooting/redirect-uri-issues.md
エラー 4709(「リダイレクト URI の不一致」)は、最もよくある OAuth エラーです。 末尾のスラッシュや http と https の違いも含め、完全に一致させる必要があります。
主な学び
重要な発見:
-
リフレッシュトークンのローテーション
- リフレッシュのたびに、新しいリフレッシュトークンが返されます
- 古いリフレッシュトークンは無効になります
- 新しいトークンを保存できないと、4735 エラーが発生します
- 参照:トークンのリフレッシュ
-
S2S OAuth では Redis、ユーザー OAuth ではデータベースを使用
- S2S:アカウント全体で 1 つのトークン → Redis(一時的)
- ユーザー:ユーザーごとのトークン → データベース(永続的)
- 参照:S2S OAuth と Redis と ユーザー OAuth と MySQL
-
リダイレクト URI は完全に一致する必要があります
- 末尾のスラッシュが重要です:
/callback≠/callback/ - プロトコルが重要です:
http://≠https:// - ポートが重要です:
:3000≠:3001 - 参照:リダイレクト URI の問題
- 末尾のスラッシュが重要です:
-
パブリッククライアントには PKCE が必要です
- モバイルアプリではシークレットを保持できません
- SPA ではシークレットを保持できません
- PKCE は認可コードの傍受を防ぎます
- 参照:PKCE
-
State パラメーターは CSRF を防ぎます
- リダイレクトの前にランダムな state を生成します
- セッションに保存します
- コールバック時に検証します
- 参照:State パラメーター
-
トークンの保存時には暗号化が必要です
- トークンを平文で保存しないでください
- 最低でも AES-256 を使用してください
- 参照:ユーザー OAuth と MySQL
-
JWT アプリタイプは非推奨です(2023 年 6 月)
- 新しい JWT アプリは作成できません
- 既存のアプリは引き続き動作しますが、将来的にサポートが終了します
- S2S OAuth またはユーザー OAuth に移行してください
-
スコープレベルによって認可要件が決まります
- 接尾辞なし(ユーザーレベル):どのユーザーでも認可できます
:admin:管理者ロールが必要です:master:アカウント所有者が必要です(複数アカウントの場合)- 参照:スコープのアーキテクチャ
-
認可コードの有効期限は 5 分です
- コードをすぐにトークンと交換してください
- 認可コードをキャッシュしないでください
- 参照:トークンのライフサイクル
-
デバイスフローではポーリングが必要です
/devicecodeが返す間隔(通常は 5 秒)でポーリングしてくださいauthorization_pending、slow_down、expired_tokenを処理してください- 参照:デバイスフロー
クイックリファレンス
「どの OAuth フローを使えばよいですか?」
「リダイレクト URI 不一致エラー(4709)」
「トークンの有効期限が切れた、または無効です」
→ トークンの問題
「リフレッシュトークンが無効です(4735)」
→ トークンのリフレッシュ - 新しいリフレッシュトークンを保存する必要があります
「スコープ不一致エラー(4711)」
→ スコープの問題
「OAuth アプリを保護するにはどうすればよいですか?」
→ PKCE + State パラメーター
「自動リフレッシュを実装するにはどうすればよいですか?」
「Classic スコープと Granular スコープの違いは何ですか?」
「エラーコードの意味を知りたい」
→ 一般的なエラー
ドキュメントのバージョン
Zoom OAuth API v2(2024 年以降)に基づいています
非推奨: JWT アプリタイプ(2023 年 6 月)
コーディングをお楽しみください!
どのフローが用途に合っているかを理解するには、OAuth フローから始めてください!
環境変数
- 標準化された
.envキーと各値の取得先については、references/environment-variables.md を参照してください。