zoom-oauth

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zoom OAuth

Zoom OAuth

Background reference for Zoom auth and token lifecycle behavior. Prefer
setup-zoom-oauth
first, then use this skill for the exact flow, scope, and error details.
Zoom身份认证和令牌生命周期行为的背景参考,请优先使用
setup-zoom-oauth
,再通过本技能获取具体的流程、作用域和错误详情。

Zoom OAuth

Zoom OAuth

Authentication and authorization for Zoom APIs.
Zoom API的身份验证与授权说明。

📖 Complete Documentation

📖 完整文档

For comprehensive guides, production patterns, and troubleshooting, see Integrated Index section below.
Quick navigation:
  • 5-Minute Runbook - Preflight checks before deep debugging
  • OAuth Flows - Which flow to use and how each works
  • Token Lifecycle - Expiration, refresh, and revocation
  • Production Examples - Redis caching, MySQL storage, auto-refresh
  • Troubleshooting - Error codes 4700-4741
如需全面指南、生产模式和故障排查方案,请参阅下方的集成索引部分
快速导航:
  • 5分钟运行手册 - 深度调试前的预检检查
  • OAuth 流程 - 不同场景适用的流程及工作原理
  • 令牌生命周期 - 过期、刷新和吊销规则
  • 生产示例 - Redis缓存、MySQL存储、自动刷新实现
  • 故障排查 - 4700-4741错误码说明

Prerequisites

前置条件

  • Zoom app created in Marketplace
  • Client ID and Client Secret
  • For S2S OAuth: Account ID
  • 已在Zoom市场创建应用
  • 拥有Client ID和Client Secret
  • 若使用S2S OAuth:需提供Account ID

Four Authorization Use Cases

四种授权使用场景

Use CaseApp TypeGrant TypeIndustry Name
Account AuthorizationServer-to-Server
account_credentials
Client Credentials Grant, M2M, Two-legged OAuth
User AuthorizationGeneral
authorization_code
Authorization Code Grant, Three-legged OAuth
Device AuthorizationGeneral
urn:ietf:params:oauth:grant-type:device_code
Device Authorization Grant (RFC 8628)
Client AuthorizationGeneral
client_credentials
Client Credentials Grant (chatbot-scoped)
场景应用类型Grant Type行业通用名称
账户授权服务端到服务端
account_credentials
客户端凭证授权、M2M、双阶段OAuth
用户授权通用
authorization_code
授权码授权、三阶段OAuth
设备授权通用
urn:ietf:params:oauth:grant-type:device_code
设备授权(RFC 8628)
客户端授权通用
client_credentials
客户端凭证授权(仅限聊天机器人作用域)

Industry Terminology

行业术语

TermMeaning
Two-legged OAuthNo user involved (client ↔ server)
Three-legged OAuthUser involved (user ↔ client ↔ server)
M2MMachine-to-Machine (backend services)
Public clientCan't keep secrets (mobile, SPA) → use PKCE
Confidential clientCan keep secrets (backend servers)
PKCEProof Key for Code Exchange (RFC 7636), pronounced "pixy"
术语含义
双阶段OAuth无用户参与(客户端 ↔ 服务端)
三阶段OAuth有用户参与(用户 ↔ 客户端 ↔ 服务端)
M2M机器到机器(后端服务场景)
公开客户端无法安全存储密钥(移动端、SPA)→ 需使用PKCE
机密客户端可以安全存储密钥(后端服务)
PKCE授权码交换证明密钥(RFC 7636),发音为"pixy"

Which Flow Should I Use?

我应该使用哪种流程?

                              ┌─────────────────────┐
                              │  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    │         │                 │
          └─────────────────────────┘         └─────────────────┘

                              ┌─────────────────────┐
                              │  你要开发什么类型的  │
                              │  应用?              │
                              └──────────┬──────────┘
                    ┌────────────────────┼────────────────────┐
                    │                    │                    │
                    ▼                    ▼                    ▼
          ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
          │  后端自动化     │  │  面向其他用户/   │  │  仅聊天机器人   │
          │  (自有账户)   │  │  账户的应用      │  │  (团队聊天)    │
          └────────┬────────┘  └────────┬────────┘  └────────┬────────┘
                   │                    │                    │
                   ▼                    │                    ▼
          ┌─────────────────┐           │           ┌─────────────────┐
          │    账户授权      │           │           │     客户端授权   │
          │   (S2S OAuth)   │           │           │   (聊天机器人)   │
          └─────────────────┘           │           └─────────────────┘
                              ┌─────────────────────┐
                              │  设备是否有浏览器?   │
                              └──────────┬──────────┘
                         ┌───────────────┴───────────────┐
                         │ 否                          是│
                         ▼                               ▼
          ┌─────────────────────────┐         ┌─────────────────┐
          │        设备授权          │         │      用户授权     │
          │     (设备流程)           │         │  (授权码流程)     │
          │                         │         │ + PKCE(若为公开  │
          │ 示例:                   │         │   客户端)        │
          │ • 智能电视               │         │                   │
          │ • Meeting SDK设备        │         │                   │
          └─────────────────────────┘         └─────────────────┘

Account Authorization (Server-to-Server OAuth)

账户授权(Server-to-Server OAuth)

For backend automation without user interaction.
适用于无需用户交互的后端自动化场景。

Request Access Token

请求访问令牌

bash
POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={ACCOUNT_ID}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
bash
POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={ACCOUNT_ID}

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

Response

返回结果

json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "user:read:user:admin",
  "api_url": "https://api.zoom.us"
}
json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "user:read:user:admin",
  "api_url": "https://api.zoom.us"
}

Refresh

刷新规则

Access tokens expire after 1 hour. No separate refresh flow - just request a new token.

访问令牌1小时后过期,无单独的刷新流程,直接请求新令牌即可。

User Authorization (Authorization Code Flow)

用户授权(授权码流程)

For apps that act on behalf of users.
适用于代表用户执行操作的应用。

Step 1: Redirect User to Authorize

步骤1:重定向用户到授权页面

https://zoom.us/oauth/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}
Use
https://zoom.us/oauth/authorize
for consent, but
https://zoom.us/oauth/token
for token exchange.
Optional Parameters:
ParameterDescription
state
CSRF protection, maintains state through flow
code_challenge
For PKCE (see below)
code_challenge_method
S256
or
plain
(default: plain)
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)

Step 2: User Authorizes

步骤2:用户授权

  • User signs in and grants permission
  • Redirects to
    redirect_uri
    with authorization code:
    https://example.com/?code={AUTHORIZATION_CODE}
  • 用户登录并授予权限
  • 授权完成后重定向到
    redirect_uri
    并携带授权码:
    https://example.com/?code={AUTHORIZATION_CODE}

Step 3: Exchange Code for Token

步骤3:用授权码交换令牌

bash
POST https://zoom.us/oauth/token?grant_type=authorization_code&code={CODE}&redirect_uri={REDIRECT_URI}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
With PKCE: Add
code_verifier
parameter.
bash
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
参数。

Response

返回结果

json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "refresh_token": "eyJ...",
  "expires_in": 3600,
  "scope": "user:read:user",
  "api_url": "https://api.zoom.us"
}
json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "refresh_token": "eyJ...",
  "expires_in": 3600,
  "scope": "user:read:user",
  "api_url": "https://api.zoom.us"
}

Refresh Token

刷新令牌

bash
POST https://zoom.us/oauth/token?grant_type=refresh_token&refresh_token={REFRESH_TOKEN}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
  • Access tokens expire after 1 hour
  • Refresh token lifetime can vary; ~90 days is common for some user-based flows. Treat it as configuration/behavior that can change and rely on runtime errors + re-auth fallback.
  • Always use the latest refresh token for the next request
  • If refresh token expires, redirect user to authorization URL to restart flow
bash
POST https://zoom.us/oauth/token?grant_type=refresh_token&refresh_token={REFRESH_TOKEN}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
  • 访问令牌1小时后过期
  • 刷新令牌有效期不固定,部分用户场景通常为90天,建议将其视为可配置的可变行为,依赖运行时错误+重新授权作为兜底方案
  • 后续请求始终使用最新的刷新令牌
  • 若刷新令牌过期,重定向用户到授权URL重启流程

User-Level vs Account-Level Apps

用户级与账户级应用对比

TypeWho Can AuthorizeScope Access
User-levelAny individual userScoped to themselves
Account-levelUser with admin permissionsAccount-wide access (admin scopes)

类型可授权角色作用域访问权限
用户级任意个人用户仅授权用户自身的数据范围
账户级拥有管理员权限的用户全账户范围访问(管理员作用域)

Device Authorization (Device Flow)

设备授权(设备流程)

For devices without browsers (e.g., Meeting SDK apps).
适用于无浏览器的设备(例如Meeting SDK应用)。

Prerequisites

前置条件

Enable "Use App on Device" in: Features > Embed > Enable Meeting SDK
在以下路径开启「在设备上使用应用」:功能 > 嵌入 > 启用Meeting SDK

Step 1: Request Device Code

步骤1:请求设备码

bash
POST https://zoom.us/oauth/devicecode?client_id={CLIENT_ID}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
bash
POST https://zoom.us/oauth/devicecode?client_id={CLIENT_ID}

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

Response

返回结果

json
{
  "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
}
json
{
  "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
}

Step 2: User Authorization

步骤2:用户授权

Direct user to:
  • verification_uri
    and display
    user_code
    for manual entry, OR
  • verification_uri_complete
    (user code prefilled)
User signs in and allows the app.
引导用户操作:
  • 访问
    verification_uri
    并手动输入展示的
    user_code
    ,或者
  • 直接访问
    verification_uri_complete
    (已自动填充user_code)
用户登录并允许应用访问权限。

Step 3: Poll for Token

步骤3:轮询获取令牌

Poll at the
interval
(5 seconds) until user authorizes:
bash
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)}
按照返回的
interval
(默认5秒)轮询接口,直到用户完成授权:
bash
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)}

Response

返回结果

json
{
  "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"
}
json
{
  "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"
}

Polling Responses

轮询响应说明

ResponseMeaningAction
Token returnedUser authorizedStore tokens, done
error: authorization_pending
User hasn't authorized yetKeep polling at interval
error: slow_down
Polling too fastIncrease interval by 5 seconds
error: expired_token
Device code expired (15 min)Restart flow from Step 1
error: access_denied
User denied authorizationHandle denial, don't retry
响应含义操作
返回令牌用户已授权存储令牌,流程结束
error: authorization_pending
用户尚未完成授权按间隔继续轮询
error: slow_down
轮询频率过高轮询间隔增加5秒
error: expired_token
设备码已过期(15分钟有效期)从步骤1重启流程
error: access_denied
用户拒绝授权处理拒绝逻辑,无需重试

Polling Implementation

轮询实现示例

javascript
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
    }
  }
}
javascript
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; // 成功获取令牌
    } catch (error) {
      const err = error.response?.data?.error;
      if (err === 'authorization_pending') continue;
      if (err === 'slow_down') { interval += 5; continue; }
      throw error; // 令牌过期或用户拒绝授权
    }
  }
}

Refresh

刷新规则

Same as User Authorization. If refresh token expires, restart device flow from Step 1.

与用户授权流程一致,若刷新令牌过期,从步骤1重启设备授权流程。

Client Authorization (Chatbot)

客户端授权(聊天机器人)

For chatbot message operations only.
仅适用于聊天机器人消息操作场景。

Request Token

请求令牌

bash
POST https://zoom.us/oauth/token?grant_type=client_credentials

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
bash
POST https://zoom.us/oauth/token?grant_type=client_credentials

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

Response

返回结果

json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "imchat:bot",
  "api_url": "https://api.zoom.us"
}
json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "imchat:bot",
  "api_url": "https://api.zoom.us"
}

Refresh

刷新规则

Tokens expire after 1 hour. No refresh flow - just request a new token.

令牌1小时后过期,无刷新流程,直接请求新令牌即可。

Using Access Tokens

使用访问令牌

Call API

调用API

bash
GET https://api.zoom.us/v2/users/me

Headers:
Authorization: Bearer {ACCESS_TOKEN}
bash
GET https://api.zoom.us/v2/users/me

Headers:
Authorization: Bearer {ACCESS_TOKEN}

Me Context

Me上下文

Replace
userID
with
me
to target the token's associated user:
EndpointMethods
/v2/users/me
GET, PATCH
/v2/users/me/token
GET
/v2/users/me/meetings
GET, POST

userID
替换为
me
即可指向令牌关联的用户:
接口支持方法
/v2/users/me
GET, PATCH
/v2/users/me/token
GET
/v2/users/me/meetings
GET, POST

Revoke Access Token

吊销访问令牌

Works for all authorization types.
bash
POST https://zoom.us/oauth/revoke?token={ACCESS_TOKEN}

Headers:
Authorization: Basic {Base64(ClientID:ClientSecret)}
适用于所有授权类型。
bash
POST https://zoom.us/oauth/revoke?token={ACCESS_TOKEN}

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

Response

返回结果

json
{
  "status": "success"
}

json
{
  "status": "success"
}

PKCE (Proof Key for Code Exchange)

PKCE(授权码交换证明密钥)

For public clients that can't securely store secrets (mobile apps, SPAs, desktop apps).
适用于无法安全存储密钥的公开客户端(移动应用、SPA、桌面应用)。

When to Use PKCE

何时使用PKCE

Client TypeUse PKCE?Why
Mobile appYesCan't securely store client secret
Single Page App (SPA)YesJavaScript is visible to users
Desktop appYesBinary can be decompiled
Meeting SDK (client-side)YesRuns on user's device
Backend serverOptionalCan keep secrets, but PKCE adds security
客户端类型是否需要PKCE?原因
移动应用无法安全存储客户端密钥
单页应用(SPA)JavaScript代码对用户可见
桌面应用二进制文件可被反编译
Meeting SDK(客户端侧)运行在用户设备上
后端服务可选可安全存储密钥,但PKCE可额外提升安全性

How PKCE Works

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 ──────── │
     │                                         │                              │
┌──────────┐                              ┌──────────┐                    ┌──────────┐
│  客户端  │                              │   Zoom   │                    │   Zoom   │
│   应用   │                              │  认证服务 │                    │  令牌服务 │
└────┬─────┘                              └────┬─────┘                    └────┬─────┘
     │                                         │                              │
     │ 1. 生成code_verifier(随机值)           │                              │
     │ 2. 生成code_challenge = SHA256(verifier)                            │
     │                                         │                              │
     │ ─────── /authorize + code_challenge ──► │                              │
     │                                         │                              │
     │ ◄────── authorization_code ──────────── │                              │
     │                                         │                              │
     │ ─────────────── /token + code_verifier ─┼────────────────────────────► │
     │                                         │                              │
     │                                         │     校验:SHA256(verifier) 等于 challenge │
     │                                         │                              │
     │ ◄───────────────────────────────────────┼─────── access_token ──────── │
     │                                         │                              │

Implementation (Node.js)

实现示例(Node.js)

javascript
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
javascript
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`;

// 将pkce.verifier存储在session中供回调时使用

Token Exchange with PKCE

带PKCE的令牌交换

bash
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)}

bash
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)}

Deauthorization

取消授权

When a user removes your app, Zoom sends a webhook to your Deauthorization Notification Endpoint URL.
当用户移除你的应用时,Zoom会向你的取消授权通知端点URL发送Webhook。

Webhook Event

Webhook事件

json
{
  "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"
  }
}
json
{
  "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"
  }
}

Requirements

要求

  • Delete all associated user data after receiving this event
  • Verify webhook signature (use secret token, verification token deprecated Oct 2023)
  • Only public apps receive deauthorization webhooks (not private/dev apps)

  • 收到该事件后删除所有关联的用户数据
  • 验证Webhook签名(使用密钥令牌,验证令牌已于2023年10月废弃)
  • 仅公开应用会收到取消授权Webhook(私有/开发应用不会)

Pre-Approval Flow

预审批流程

Some Zoom accounts require Marketplace admin pre-approval before users can authorize apps.
  • Users can request pre-approval from their admin
  • Account-level apps (admin scopes) require appropriate role permissions

部分Zoom账户要求市场管理员预审批后,用户才能授权应用。
  • 用户可以向管理员申请预审批
  • 账户级应用(管理员作用域)需要对应的角色权限

Active Apps Notifier (AAN)

活跃应用通知(AAN)

In-meeting feature showing apps with real-time access to content.
  • Displays icon + tooltip with app info, content type being accessed, approving account
  • Supported: Zoom client 5.6.7+, Meeting SDK 5.9.0+

会议内功能,展示可实时访问内容的应用。
  • 展示图标+提示框,包含应用信息、访问的内容类型、审批账户
  • 支持版本:Zoom客户端5.6.7+、Meeting SDK 5.9.0+

OAuth Scopes

OAuth作用域

Scope Types

作用域类型

TypeDescriptionFor
Classic scopesLegacy scopes (user, admin, master levels)Existing apps
Granular scopesNew fine-grained scopes with optional supportNew apps
类型说明适用场景
经典作用域旧版作用域(用户、管理员、主账户级别)现有应用
细粒度作用域新增的细粒度作用域,支持可选授权新应用

Classic Scopes

经典作用域

For previously-created apps. Three levels:
  • User-level: Access to individual user's data
  • Admin-level: Account-wide access, requires admin role
  • Master-level: For master-sub account setups, requires account owner
适用于之前创建的应用,分为三个级别:
  • 用户级:访问单个用户的数据
  • 管理员级:全账户访问,需要管理员角色
  • 主账户级:适用于主-子账户架构,需要账户所有者权限

Granular Scopes

细粒度作用域

For new apps. Format:
<service>:<action>:<data_claim>:<access>
ComponentValues
service
meeting
,
webinar
,
user
,
recording
, etc.
action
read
,
write
,
update
,
delete
data_claimData category (e.g.,
participants
,
settings
)
accessempty (user),
admin
,
master
Example:
meeting:read:list_meetings:admin
适用于新应用,格式:
<服务>:<操作>:<数据项>:<访问级别>
组成部分取值示例
服务
meeting
,
webinar
,
user
,
recording
操作
read
,
write
,
update
,
delete
数据项数据类别(例如
participants
,
settings
访问级别空(用户级)、
admin
master
示例:
meeting:read:list_meetings:admin

Optional Scopes

可选作用域

Granular scopes can be marked as optional - users choose whether to grant them.
Basic authorization (uses build flow defaults):
https://zoom.us/oauth/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}
Advanced authorization (custom scopes per request):
https://zoom.us/oauth/authorize?client_id={CLIENT_ID}&response_type=code&redirect_uri={REDIRECT_URI}&scope={required_scopes}&optional_scope={optional_scopes}
Include previously granted scopes:
https://zoom.us/oauth/authorize?...&include_granted_scopes&scope={additional_scopes}
细粒度作用域可以标记为可选,用户可以自主选择是否授权。
基础授权(使用构建流程默认配置):
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}

Migrating Classic to Granular

经典作用域迁移到细粒度作用域

  1. Manage > select app > edit
  2. Scope page > Development tab > click Migrate
  3. Review auto-assigned granular scopes, remove unnecessary, mark optional
  4. Test
  5. Production tab > click Migrate
Notes:
  • No review needed if only migrating or reducing scopes
  • Existing user tokens continue with classic scope values until re-authorization
  • New users get granular scopes after migration

  1. 管理 > 选择应用 > 编辑
  2. 作用域页面 > 开发选项卡 > 点击迁移
  3. 检查自动分配的细粒度作用域,移除不需要的项,标记可选作用域
  4. 测试
  5. 生产选项卡 > 点击迁移
注意:
  • 仅迁移或减少作用域无需重新审核
  • 现有用户令牌在重新授权前将继续使用经典作用域值
  • 迁移后新用户将获取细粒度作用域

Common Error Codes

常见错误码

CodeMessageSolution
4700Token cannot be emptyCheck Authorization header has valid token
4702/4704Invalid clientVerify Client ID and Client Secret
4705Grant type not supportedUse:
account_credentials
,
authorization_code
,
urn:ietf:params:oauth:grant-type:device_code
, or
client_credentials
4706Client ID or secret missingAdd credentials to header or request params
4709Redirect URI mismatchEnsure redirect_uri matches app configuration exactly (including trailing slash)
4711Refresh token invalidToken scopes don't match client scopes
4717App has been disabledContact Zoom support
4733Code is expiredAuthorization codes expire in 5 minutes - restart flow
4734Invalid authorization codeRegenerate authorization code
4735Owner of token does not existUser was removed from account - re-authorize
4741Token has been revokedUse the most recent token from latest authorization
See
references/oauth-errors.md
for complete error list.

错误码消息解决方案
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

Quick Reference

快速参考

FlowGrant TypeToken ExpiryRefresh
Account (S2S)
account_credentials
1 hourRequest new token
User
authorization_code
1 hourUse refresh_token (90 day expiry)
Device
urn:ietf:params:oauth:grant-type:device_code
1 hourUse refresh_token (90 day expiry)
Client (Chatbot)
client_credentials
1 hourRequest new token

流程Grant Type令牌有效期刷新方式
账户授权(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小时请求新令牌

Demo Guidance

演示应用指南

If you build an OAuth demo app, document its runtime base URL in that demo project's own README or
.env.example
, not in this shared skill.
如果你构建了OAuth演示应用,请将运行时基础URL记录在演示项目自身的README或
.env.example
中,不要写在本共享技能文档中。

Resources

资源

Integrated Index

集成索引

This section was migrated from
SKILL.md
.
本部分从
SKILL.md
迁移而来。

Quick Start Path

快速入门路径

If you're new to Zoom OAuth, follow this order:
  1. Run preflight checks firstRUNBOOK.md
  2. Choose your OAuth flowconcepts/oauth-flows.md
    • 4 flows: S2S (backend), User (SaaS), Device (no browser), Chatbot
    • Decision matrix: Which flow fits your use case?
  3. Understand token lifecycleconcepts/token-lifecycle.md
    • CRITICAL: How tokens expire, refresh, and revoke
    • Common pitfalls: refresh token rotation
  4. Implement your flow → Jump to examples:
    • Backend automation → examples/s2s-oauth-redis.md
    • SaaS app → examples/user-oauth-mysql.md
    • Mobile/SPA → examples/pkce-implementation.md
    • Device (TV/kiosk) → examples/device-flow.md
  5. Fix redirect URI issuestroubleshooting/redirect-uri-issues.md
    • Most common OAuth error: Redirect URI mismatch
  6. Implement token refreshexamples/token-refresh.md
    • Automatic middleware pattern
    • Handle refresh token rotation
  7. Troubleshoot errorstroubleshooting/common-errors.md
    • Error code tables (4700-4741 range)
    • Quick diagnostic workflow

如果你是Zoom OAuth新手,请按以下顺序学习:
  1. 首先运行预检检查RUNBOOK.md
  2. 选择你的OAuth流程concepts/oauth-flows.md
    • 4种流程:S2S(后端)、用户(SaaS)、设备(无浏览器)、聊天机器人
    • 决策矩阵:匹配你的使用场景的最优流程
  3. 理解令牌生命周期concepts/token-lifecycle.md
    • 关键:令牌过期、刷新和吊销规则
    • 常见陷阱:刷新令牌轮换
  4. 实现你的流程 → 跳转到对应示例:
    • 后端自动化 → examples/s2s-oauth-redis.md
    • SaaS应用 → examples/user-oauth-mysql.md
    • 移动端/SPA → examples/pkce-implementation.md
    • 设备(电视/自助终端)→ examples/device-flow.md
  5. 修复重定向URI问题troubleshooting/redirect-uri-issues.md
    • 最常见的OAuth错误:重定向URI不匹配
  6. 实现令牌刷新examples/token-refresh.md
    • 自动中间件模式
    • 处理刷新令牌轮换
  7. 排查错误troubleshooting/common-errors.md
    • 错误码表(4700-4741范围)
    • 快速诊断流程

Documentation Structure

文档结构

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

oauth/
├── SKILL.md                           # 技能总览
├── SKILL.md                           # 本文件 - 导航指南
├── concepts/                          # 核心OAuth概念
│   ├── oauth-flows.md                # 4种流程:S2S、用户、设备、聊天机器人
│   ├── token-lifecycle.md            # 过期、刷新、吊销
│   ├── pkce.md                       # 公开客户端的PKCE安全机制
│   ├── scopes-architecture.md        # 经典作用域 vs 细粒度作用域
│   └── state-parameter.md            # 使用state参数的CSRF防护
├── examples/                          # 完整可运行代码
│   ├── s2s-oauth-basic.md            # S2S OAuth最小示例
│   ├── s2s-oauth-redis.md            # 带Redis缓存的S2S OAuth(生产级)
│   ├── user-oauth-basic.md           # 用户OAuth最小示例
│   ├── user-oauth-mysql.md           # 带MySQL+加密的用户OAuth(生产级)
│   ├── device-flow.md                # 设备授权流程
│   ├── pkce-implementation.md        # 适用于SPA/移动应用的PKCE实现
│   └── token-refresh.md              # 自动刷新中间件模式
├── troubleshooting/                   # 问题排查指南
│   ├── common-errors.md              # 4700-4741错误码
│   ├── redirect-uri-issues.md        # 最常见的OAuth错误
│   ├── token-issues.md               # 过期、吊销、无效令牌问题
│   └── scope-issues.md               # 作用域不匹配错误
└── references/                        # 参考文档
    ├── oauth-errors.md                # 完整错误码参考
    ├── classic-scopes.md              # 经典作用域参考
    └── granular-scopes.md             # 细粒度作用域参考

By Use Case

按使用场景分类

I want to automate Zoom tasks on my own account

我要自动化自有账户的Zoom任务

  1. OAuth Flows - S2S OAuth explained
  2. S2S OAuth Redis - Production pattern with Redis caching
  3. Token Lifecycle - 1hr token, no refresh
  1. OAuth流程 - S2S OAuth说明
  2. S2S OAuth Redis示例 - 带Redis缓存的生产模式
  3. 令牌生命周期 - 1小时令牌有效期,无刷新流程

I want to build a SaaS app for other Zoom users

我要为其他Zoom用户构建SaaS应用

  1. OAuth Flows - User OAuth explained
  2. User OAuth MySQL - Production pattern with encryption
  3. Token Refresh - Automatic refresh middleware
  4. Redirect URI Issues - Fix most common error
  1. OAuth流程 - 用户OAuth说明
  2. 用户OAuth MySQL示例 - 带加密的生产模式
  3. 令牌刷新 - 自动刷新中间件
  4. 重定向URI问题 - 修复最常见错误

I want to build a mobile or SPA app

我要构建移动或SPA应用

  1. PKCE - Why PKCE is required for public clients
  2. PKCE Implementation - Complete code example
  3. State Parameter - CSRF protection
  1. PKCE - 为什么公开客户端必须使用PKCE
  2. PKCE实现示例 - 完整代码示例
  3. State参数 - CSRF防护

I want to build an app for devices without browsers (TV, kiosk)

我要为无浏览器的设备(电视、自助终端)构建应用

  1. OAuth Flows - Device flow explained
  2. Device Flow Example - Complete polling implementation
  3. Common Errors - Device-specific errors
  1. OAuth流程 - 设备流程说明
  2. 设备流程示例 - 完整轮询实现
  3. 常见错误 - 设备相关错误

I'm building a Team Chat bot

我要构建团队聊天机器人

  1. OAuth Flows - Chatbot flow explained
  2. S2S OAuth Basic - Similar pattern, different grant type
  3. Scopes Architecture - Chatbot-specific scopes
  1. OAuth流程 - 聊天机器人流程说明
  2. S2S OAuth基础示例 - 类似模式,不同授权类型
  3. 作用域架构 - 聊天机器人专属作用域

I'm getting redirect URI errors (4709)

我遇到重定向URI错误(4709)

  1. Redirect URI Issues - START HERE!
  2. Common Errors - Error details
  3. User OAuth Basic - See correct pattern
  1. 重定向URI问题 - 从这里开始排查!
  2. 常见错误 - 错误详情
  3. 用户OAuth基础示例 - 查看正确实现模式

I'm getting token errors (4700-4741)

我遇到令牌错误(4700-4741)

  1. Token Issues - Diagnostic workflow
  2. Token Lifecycle - Understand expiration
  3. Token Refresh - Implement auto-refresh
  4. Common Errors - Error code tables
  1. 令牌问题 - 诊断流程
  2. 令牌生命周期 - 理解过期规则
  3. 令牌刷新 - 实现自动刷新
  4. 常见错误 - 错误码表

I'm getting scope errors (4711)

我遇到作用域错误(4711)

  1. Scope Issues - Mismatch causes
  2. Scopes Architecture - Classic vs Granular
  3. Classic Scopes - Complete scope reference
  4. Granular Scopes - Granular scope reference
  1. 作用域问题 - 不匹配原因
  2. 作用域架构 - 经典 vs 细粒度作用域
  3. 经典作用域 - 完整作用域参考
  4. 细粒度作用域 - 细粒度作用域参考

I need to refresh tokens

我需要实现令牌刷新

  1. Token Lifecycle - When to refresh
  2. Token Refresh - Middleware pattern
  3. Token Issues - Common mistakes
  1. 令牌生命周期 - 刷新时机
  2. 令牌刷新 - 中间件模式
  3. 令牌问题 - 常见错误

I want to understand the difference between Classic and Granular scopes

我想了解经典和细粒度作用域的区别

  1. Scopes Architecture - Complete comparison
  2. Classic Scopes -
    resource:level
    format
  3. Granular Scopes -
    service:action:data_claim:access
    format
  1. 作用域架构 - 完整对比
  2. 经典作用域 -
    resource:level
    格式
  3. 细粒度作用域 -
    service:action:data_claim:access
    格式

I need to secure my OAuth implementation

我需要加固OAuth实现的安全性

  1. PKCE - Public client security
  2. State Parameter - CSRF protection
  3. User OAuth MySQL - Token encryption at rest
  1. PKCE - 公开客户端安全
  2. State参数 - CSRF防护
  3. 用户OAuth MySQL示例 - 静态令牌加密

I want to migrate from JWT app to S2S OAuth

我要从JWT应用迁移到S2S OAuth

  1. S2S OAuth Redis - Modern replacement
  2. Token Lifecycle - Different token behavior
Note: JWT App Type was deprecated in June 2023. Migrate to S2S OAuth for server-to-server automation.

  1. S2S OAuth Redis示例 - 现代替代方案
  2. 令牌生命周期 - 不同的令牌行为
注意:JWT应用类型已于2023年6月废弃,服务端到服务端自动化场景请迁移到S2S OAuth。

Most Critical Documents

最重要的文档

1. OAuth Flows (DECISION DOCUMENT)

1. OAuth流程(决策文档)

concepts/oauth-flows.md
Understand which of the 4 flows to use:
  • S2S OAuth: Backend automation (your account)
  • User OAuth: SaaS apps (users authorize you)
  • Device Flow: Devices without browsers
  • Chatbot: Team Chat bots only
concepts/oauth-flows.md
了解4种流程的适用场景:
  • S2S OAuth:后端自动化(自有账户)
  • 用户OAuth:SaaS应用(用户授权访问)
  • 设备流程:无浏览器的设备
  • 聊天机器人:仅团队聊天机器人场景

2. Token Lifecycle (MOST COMMON ISSUE)

2. 令牌生命周期(最常见问题来源)

concepts/token-lifecycle.md
99% of OAuth issues stem from misunderstanding:
  • Token expiration (1 hour for all flows)
  • Refresh token rotation (must save new refresh token)
  • Revocation behavior (invalidates all tokens)
concepts/token-lifecycle.md
99%的OAuth问题都源于对以下内容的误解:
  • 令牌过期(所有流程的访问令牌有效期都是1小时)
  • 刷新令牌轮换(必须保存新的刷新令牌)
  • 吊销行为(会使所有令牌失效)

3. Redirect URI Issues (MOST COMMON ERROR)

3. 重定向URI问题(最常见错误)

troubleshooting/redirect-uri-issues.md
Error 4709 ("Redirect URI mismatch") is the #1 OAuth error. Must match EXACTLY (including trailing slash, http vs https).

troubleshooting/redirect-uri-issues.md
错误4709(「重定向URI不匹配」)是排名第一的OAuth错误,必须与配置完全一致(包括末尾斜杠、http/https协议)。

Key Learnings

核心要点

Critical Discoveries:

关键发现:

  1. Refresh Token Rotation
    • Each refresh returns a NEW refresh token
    • Old refresh token becomes invalid
    • Failure to save new token causes 4735 errors
    • See: Token Refresh
  2. S2S OAuth Uses Redis, User OAuth Uses Database
    • S2S: Single token for entire account → Redis (ephemeral)
    • User: Per-user tokens → Database (persistent)
    • See: S2S OAuth Redis vs User OAuth MySQL
  3. Redirect URI Must Match EXACTLY
    • Trailing slash matters:
      /callback
      /callback/
    • Protocol matters:
      http://
      https://
    • Port matters:
      :3000
      :3001
    • See: Redirect URI Issues
  4. PKCE Required for Public Clients
    • Mobile apps CANNOT keep secrets
    • SPAs CANNOT keep secrets
    • PKCE prevents authorization code interception
    • See: PKCE
  5. State Parameter Prevents CSRF
    • Generate random state before redirect
    • Store in session
    • Verify on callback
    • See: State Parameter
  6. Token Storage Must Be Encrypted
    • NEVER store tokens in plain text
    • Use AES-256 minimum
    • See: User OAuth MySQL
  7. JWT App Type is Deprecated (June 2023)
    • No new JWT apps can be created
    • Existing apps still work but will eventually be sunset
    • Migrate to S2S OAuth or User OAuth
  8. Scope Levels Determine Authorization Requirements
    • No suffix (user-level): Any user can authorize
    • :admin
      : Requires admin role
    • :master
      : Requires account owner (multi-account)
    • See: Scopes Architecture
  9. Authorization Codes Expire in 5 Minutes
    • Exchange code for token immediately
    • Don't cache authorization codes
    • See: Token Lifecycle
  10. Device Flow Requires Polling
    • Poll at interval returned by
      /devicecode
      (usually 5s)
    • Handle
      authorization_pending
      ,
      slow_down
      ,
      expired_token
    • See: Device Flow

  1. 刷新令牌轮换
    • 每次刷新都会返回一个新的刷新令牌
    • 旧的刷新令牌会失效
    • 未保存新令牌会导致4735错误
    • 参考:令牌刷新
  2. S2S OAuth使用Redis,用户OAuth使用数据库
    • S2S:全账户共用单个令牌 → Redis(临时存储)
    • 用户:每个用户单独的令牌 → 数据库(持久存储)
    • 参考:S2S OAuth Redis示例 对比 用户OAuth MySQL示例
  3. 重定向URI必须完全匹配
    • 末尾斜杠会影响匹配:
      /callback
      /callback/
    • 协议会影响匹配:
      http://
      https://
    • 端口会影响匹配:
      :3000
      :3001
    • 参考:重定向URI问题
  4. 公开客户端必须使用PKCE
    • 移动应用无法安全存储密钥
    • SPA无法安全存储密钥
    • PKCE可防止授权码被拦截
    • 参考:PKCE
  5. State参数可防止CSRF
    • 重定向前生成随机state
    • 存储在session中
    • 回调时验证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
      状态
    • 参考:设备流程

Quick Reference

快速查询

"Which OAuth flow should I use?"

「我应该使用哪种OAuth流程?」

OAuth Flows
OAuth流程

"Redirect URI mismatch error (4709)"

「重定向URI不匹配错误(4709)」

Redirect URI Issues
重定向URI问题

"Token expired or invalid"

「令牌过期或无效」

Token Issues
令牌问题

"Refresh token invalid (4735)"

「刷新令牌无效(4735)」

Token Refresh - Must save new refresh token
令牌刷新 - 必须保存新的刷新令牌

"Scope mismatch error (4711)"

「作用域不匹配错误(4711)」

Scope Issues
作用域问题

"How do I secure my OAuth app?"

「如何加固OAuth应用的安全性?」

PKCE + State Parameter
PKCE + State参数

"How do I implement auto-refresh?"

「如何实现自动刷新?」

Token Refresh
令牌刷新

"What's the difference between Classic and Granular scopes?"

「经典和细粒度作用域有什么区别?」

Scopes Architecture
作用域架构

"What error code means what?"

「错误码对应的含义是什么?」

Common Errors

常见错误

Document Version

文档版本

Based on Zoom OAuth API v2 (2024+)
Deprecated: JWT App Type (June 2023)

Happy coding!
Remember: Start with OAuth Flows to understand which flow fits your use case!
基于Zoom OAuth API v2(2024+版本)
已废弃: JWT应用类型(2023年6月)

编码愉快!
记住:首先查看OAuth流程,了解哪种流程适合你的使用场景!

Environment Variables

环境变量

  • See references/environment-variables.md for standardized
    .env
    keys and where to find each value.
标准化的
.env
键名及取值获取方式请参考references/environment-variables.md