尧图精选

Zoom Meeting SDK 机器人认证实战指南:JWT 签名、ZAK 与 OBF 三类令牌在 knowledge-work-plugins 中的完整解析

🕒 发布时间:2026/9/13 14:22:26 📁 来源:尧图网络
Zoom Meeting SDK 机器人认证实战指南JWT 签名、ZAK 与 OBF 三类令牌在 knowledge-work-plugins 中的完整解析【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins在 Zoom 生态中构建会议纪要、自动录制、AI 助手类会议机器人时最常见的开发困惑集中在认证体系上JWT 签名到底有没有被废弃ZAK 令牌是不是必须来自会议参会者2026 年 2 月 23 日后 OBFOn-Behalf-Of令牌何时成为硬性要求本文基于 bot-authentication.mdZoom Meeting SDK 机器人认证参考文档逐层拆解这三类令牌的用途、生成方式、适用范围与互斥关系并结合本仓库中 authorization.md、signature-playbook.md 和 linux/SKILL.md 等配套文档给出可复制的签名代码、REST API 调用示例与完整的入会流程帮助你在 Web 端或 Linux 无头环境中把机器人认证链路一次性做对。一、三类令牌总览谁负责什么Meeting SDK 的认证并非单一令牌而是由三类各司其职的凭证组合完成。原文档给出的总览表如下令牌用途是否必须是否废弃JWT 签名JWT Signature初始化/认证 Meeting SDK必须否ZAK 令牌以某个 Zoom 用户身份完成认证否视场景而定否OBF 令牌以用户归因attribution方式加入外部会议否2026 年 2 月起外部会议必需否三者的关系可以概括为JWT 签名是每次入会的入场券ZAK 是证明这个应用代表某个已认证 Zoom 用户的短时效凭证OBF 则进一步把应用绑定到当前确实在会议中的某个具体用户身上。理解了这条主线索后面所有的 API 调用和 join 参数都容易对号入座。二、头号误区JWT App Type 废弃 ≠ JWT 签名废弃这是本领域排名第一的混淆来源原文档专门用一张对照表澄清术语它是什么状态JWT App Type用于 REST API 认证的 Zoom 应用类型已废弃迁移到 Server-to-Server OAuthJWT 签名使用 SDK 凭据生成的令牌用于认证 Meeting SDK仍然必需未废弃关键结论JWT App Type 的废弃与 Meeting SDK 完全无关SDK 认证依旧依赖 JWT 签名。仓库中的 signature-playbook.md 也在排查规则中强调了这一点如果开发者把 REST API 的 OAuth 令牌或 Marketplace 的 JWT app-type 令牌拿来当 Meeting SDK 签名使用应当立即停下澄清——它们不是同一个东西混用是join failed的高频根因之一。三、JWT 签名每次都必需3.1 它是什么、何时使用JWT 签名用于向 Zoom 证明你的应用有权调用 Meeting SDK必须在服务端用 SDK 的 Client ID 与 Client Secret 生成绝不可把 SDK Secret 放到客户端代码里。每一次 Meeting SDK 入会都需要它没有例外。仓库中的 authorization.md 列出了 JWT 载荷中各 claim 的含义可作为签名生成的字段清单Claim说明sdkKey你的 SDK Keymn会议号仅数字role0 参会者1 主持人iat签发时间戳exp过期时间戳tokenExp令牌过期时间戳3.2 服务端生成示例Node.js jsrsasign原文档给出的标准生成函数如下// Server-side (Node.js) const KJUR require(jsrsasign); function generateSignature(sdkKey, sdkSecret, meetingNumber, role) { const iat Math.round(Date.now() / 1000) - 30; // 30 秒前 const exp iat 60 * 60 * 2; // iat 起 2 小时后过期 const payload { sdkKey: sdkKey, // 你的 SDK Client ID mn: meetingNumber, // 要加入的会议号 role: role, // 0 participant, 1 host iat: iat, exp: exp, tokenExp: exp }; const header { alg: HS256, typ: JWT }; return KJUR.jws.JWS.sign(HS256, JSON.stringify(header), JSON.stringify(payload), sdkSecret // 你的 SDK Client Secret ); }仓库的 SKILL.md 中还给出了把它包装成生产级后端接口的写法Express 风格补充了两个实操细节会议号要先String(meetingNumber).replace(/\D/g, )剔除非数字字符role 要用parseInt(role, 10)强制转成数字——这正是 signature-playbook.md 归纳的Invalid signature典型成因mn格式错误、role 类型错误。// server.js (Node.js example) app.post(/api/signature, (req, res) { const { meetingNumber, role } req.body; const iat Math.floor(Date.now() / 1000) - 30; const exp iat 60 * 60 * 2; const header { alg: HS256, typ: JWT }; const payload { sdkKey: process.env.ZOOM_SDK_KEY, mn: String(meetingNumber).replace(/\D/g, ), role: parseInt(role, 10), iat, exp, tokenExp: exp }; const signature KJUR.jws.JWS.sign(HS256, JSON.stringify(header), JSON.stringify(payload), process.env.ZOOM_SDK_SECRET ); res.json({ signature, sdkKey: process.env.ZOOM_SDK_KEY }); });3.3 最佳实践短时效签名Short-Lived Tokens原文档推荐在即将入会的前一刻生成签名并用一个反直觉但合规的时间窗口设计来满足 Zoom 的校验规则// 入会前一刻生成令牌 const iat Math.floor(Date.now() / 1000) - 7200; // 2 小时前 const exp Math.floor(Date.now() / 1000) 10; // 10 秒后过期 // 这样设计的原因 // - exp 很短安全性 // - exp - iat 2 小时Zoom 硬性要求 // - 令牌在使用前即刻生成这套iat 回拨 2 小时、exp 只留 10 秒的手法同时满足两个看似矛盾的约束签名实际有效期极短防泄露且exp - iat跨度不小于 2 小时Zoom 校验要求。authorization.md 的安全准则表把它进一步归纳为签名只放服务端、使用短过期时间、生成前校验用户身份signature-playbook.md 则补充了时钟偏移server clock skew是本地能跑、生产失败的常见诱因——iat/exp依赖服务器时间生产环境务必保证时钟同步。3.4 role 取值角色值说明参会者Participant0以与会者身份加入主持人Host1以主持人身份加入需为会议所有者或持有主持人密钥注意 signature-playbook.md 提到的一种失败模式role1生成签名却实际执行 join或反之会导致签名校验失败Web以主持人启动流程中 role 不匹配还会触发4003 Invalid Parameter错误此时往往还需要配合 ZAK 令牌。四、ZAK 令牌Zoom Access Key4.1 它是什么、何时使用ZAK 是一个短时效凭证证明你的机器人/应用已认证为某个具体的 Zoom 用户通过 Zoom REST API 生成。原文档给出的适用场景表场景是否需要 ZAK会议开启了仅认证用户可加入Only Authenticated Users Can Join需要以主持人身份启动会议当前主持人不在场需要主持人的 ZAK把机器人的头像改成与某用户一致需要普通的会议加入不需要4.2 获取 ZAK 令牌的两步流程第 1 步获取 OAuth Access Token授权码模式curl -X POST https://zoom.us/oauth/token \ -H Authorization: Basic {BASE64(client_id:client_secret)} \ -d grant_typeauthorization_codecode{auth_code}redirect_uri{redirect_uri}第 2 步用 Access Token 生成 ZAK 令牌curl -X GET https://api.zoom.us/v2/users/me/token?typezakttl7200 \ -H Authorization: Bearer {access_token}响应示例{ token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9... }所需的 OAuth 权限范围scope为user:read:zak这个 scope 在仓库的 granular-scopes.md 中也能交叉印证Get the users ZAK 接口对应user:read:zak管理侧为user:read:zak:admin说明 ZAK 属于用户粒度user-delegated的 OAuth 授权。4.3 在 SDK join 中使用 ZAK// Web SDK ZoomMtg.join({ signature: signature, // JWT 签名始终必需 sdkKey: clientId, meetingNumber: meetingNumber, passWord: password, // 注意大写 W userName: Meeting Bot, zak: zakToken, // 用于认证加入的 ZAK 令牌 success: (success) console.log(Joined), error: (error) console.error(error) });注意 Web 端passWord的驼峰写法大写 W——signature-playbook.md 特别指出Web Client View 下如果会议有密码而该字段拼错或缺失join 会以看起来像认证问题的方式失败排查时容易走偏。4.4 关键属性与一个高频错误原文档总结的四个属性短时效TTL 可配置通常 1–2 小时任意 ZAK 均可不需要来自会议参会者无并发限制一个服务账号可生成不限数量的令牌过期仅在入会时校验若机器人已在会中即使 ZAK 过期也不会被断开。常见错误以为 ZAK 必须来自会议参会者。正确认知任意 Zoom 账号的 ZAK 都能满足仅认证用户可加入的要求。实务上建议创建一个专用服务账号如meeting-botcompany.com为所有机器人统一签发 ZAK。五、OBF 令牌On-Behalf-Of2026 年 2 月的关键变化5.1 它是什么、为什么引入OBF 是 Zoom 新引入的凭证把机器人绑定到当前确实身在会中的某个具体用户。出于问责与透明accountability and transparency考虑它让会议中的人能清楚知道这个 SDK 应用代表哪个人。时间线要求日期外部会议External Meeting要求2026 年 2 月 23 日之前ZAK 或 OBF可选2026 年 2 月 23 日之后ZAK 或 OBF 为必需5.2 OBF 与 ZAK 的本质区别维度ZAK 令牌OBF 令牌是否需要用户在场否是—— 用户必须在会中用户离场后机器人状态保持连接立即被断开会议作用域任意会议仅限特定会议 ID归因方式泛化的身份认证绑定到具体的在场用户从源码结构看这条用户离场即断连的规则意味着 OBF 场景下机器人的生命周期策略必须与 ZAK 场景区分设计ZAK 机器人可以早于授权用户入会并一直驻留OBF 机器人则要么等用户在会中再加入要么接受加入即失败的重试成本。5.3 获取 OBF 令牌第 1 步获取 OAuth Access Token与 ZAK 相同流程。第 2 步按会议维度生成 OBF 令牌curl -X GET https://api.zoom.us/v2/users/me/token?typeonbehalfmeeting_id{meeting_id} \ -H Authorization: Bearer {access_token}响应示例{ token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9... }所需 OAuth scopeuser:read:token同样可在 granular-scopes.md 中交叉验证Get a users token 接口对应user:read:token另有user:read:token:admin、user:read:token:master等管理粒度变体。5.4 在 SDK join 中使用 OBF// Web SDK ZoomMtg.join({ signature: signature, // JWT 签名始终必需 sdkKey: clientId, meetingNumber: meetingNumber, passWord: password, userName: Meeting Bot, obfToken: obfToken, // OBF 令牌注意字段是 obfToken不是 zak success: (success) console.log(Joined), error: (error) console.error(error) });重要zak与obfToken互斥只能二选一。在 Linux C 端仓库 linux/SKILL.md 的自动加入录制示例展示了 OBF 令牌通过 join 参数app_privilege_token传入的对应关系JoinParam join_param; join_param.userType SDK_UT_WITHOUT_LOGIN; auto params join_param.param.withoutloginuserJoin; params.meetingNumber meeting_number; params.userName Recording Bot; params.psw meeting_password.c_str(); params.app_privilege_token obf_token.c_str(); // OBF 令牌 SDKError join_err meeting_service-Join(join_param);同一文档还提到app_privilege_token即 OBF也是获得 raw recording 权限的路径之一其余三种机器人是主持人/共同主持人、主持人授予录制权限、使用recording_token说明 OBF 在 Linux 无头机器人场景中还额外承担提权职能。5.5 处理授权用户尚未在会中的加入失败如果机器人先于授权用户入会SDK v6.6.10 会返回特定错误码MEETING_FAIL_AUTHORIZED_USER_NOT_INMEETING。原文档给出的重试实现// SDK v6.6.10 返回特定错误码 // MEETING_FAIL_AUTHORIZED_USER_NOT_INMEETING async function joinWithRetry(joinOptions, maxRetries 5) { for (let i 0; i maxRetries; i) { try { await ZoomMtg.join(joinOptions); return; // 成功 } catch (error) { if (error.code MEETING_FAIL_AUTHORIZED_USER_NOT_INMEETING) { console.log(User not in meeting yet. Retry ${i 1}/${maxRetries}); await sleep(3000); // 等待 3 秒 } else { throw error; // 其他错误不重试 } } } throw new Error(Max retries exceeded - user never joined meeting); }实现要点只对该特定错误码重试、其他错误直接抛出避免对用户永远不入场做无界等待。5.6 OBF 令牌的映射问题使用 OBF 前你必须能把用户映射到会议原文档给出两条路径Zoom Meetings APIGET /users/{userId}/meetings拉取用户日程中的会议日历集成解析 Google Calendar / Outlook 中的会议邀请提取 meeting_id。这一步是 OBF 工作流的实际工程瓶颈meeting_id 必须与typeonbehalfmeeting_id{meeting_id}请求里的参数严格一致。六、完整机器人入会流程Before / After 2026-026.1 2026 年 2 月之前通用流程// 1. 生成 JWT 签名始终必需 const signature await generateSignature(sdkKey, sdkSecret, meetingNumber, 0); // 2. 如会议要求认证加入则获取 ZAK let zakToken null; if (meetingRequiresAuth) { zakToken await getZAKToken(accessToken); } // 3. 加入会议 await ZoomMtg.join({ signature: signature, sdkKey: sdkKey, meetingNumber: meetingNumber, passWord: password, userName: Meeting Bot, zak: zakToken, // 可选 });6.2 2026 年 2 月之后外部会议// 1. 生成 JWT 签名始终必需 const signature await generateSignature(sdkKey, sdkSecret, meetingNumber, 0); // 2. 外部会议需获取 OBF 令牌 const obfToken await getOBFToken(accessToken, meetingNumber); // 3. 等待授权用户入会若使用 OBF // ... 实现 5.5 节的重试逻辑 ... // 4. 加入会议 await ZoomMtg.join({ signature: signature, sdkKey: sdkKey, meetingNumber: meetingNumber, passWord: password, userName: Meeting Bot, obfToken: obfToken, // 用于外部会议 });从仓库的 meeting-bots.md 可以看到这套认证流程在多技能编排里被抽象为固定的技能链先由 REST API 技能获取会议元数据并签发 OBF/ZAK再由meeting-sdk/linux技能执行以可见参会者身份加入 →StartRawRecording()→ 订阅音频/视频 delegate → 写入 PCM/YUV 或送入下游流水线需要 Zoom 托管云录制产物时再挂上 webhooks 链路。认证令牌是整条链路的第一环。七、Linux 无头机器人的落地配置对无头 Linux 机器人原文档推荐基于官方 headless 示例仓库meetingsdk-headless-linux-sample搭建其sample.config.toml的配置结构如下# 克隆示例仓库后配置 sample.config.toml [credentials] client_id YOUR_CLIENT_ID client_secret YOUR_CLIENT_SECRET [meeting] join_url https://zoom.us/j/123456789?pwdxxx # 或者 meeting_id 123456789 password abc123 # 可选令牌 zak_token ... # 用于认证加入 obf_token ... # 用于外部会议 # 用 Docker 运行 # docker compose up可以看出该示例把 5.4 节的 Web 端zak/obfToken字段统一为 TOML 配置项zak_token/obf_token凭据、会议信息与可选令牌分三层组织docker compose up一键起服务。仓库的 linux/SKILL.md 进一步说明该 C SDK 是为无头服务器环境优化的库无 GUI、GLib 事件循环驱动回调、依赖 PulseAudio 虚拟声卡其 C 端的 JWT 认证走AuthContext.jwt_tokenCreateAuthService→SDKAuth的调用链与 Web 端ZoomMtg.join的signature字段是同一枚 JWT 签名在不同平台的落点。运行环境要求 Ubuntu 22 / CentOS 8/9、x86_64、CMake 3.16原始数据PCM 32kHz 音频、YUV420 视频需要先经StartRawRecording()授权后才可订阅。八、常见错误速查表原文档把五大高频错误整理成对照表建议作为认证方案评审的 checklist错误认知实际情况修正方式JWT 签名已被废弃被废弃的只是 JWT App TypeSDK 场景继续使用 JWT 签名ZAK 必须来自会议参会者任意 Zoom 账号的 ZAK 均可用用单一服务账号统一签发ZAK 和 OBF 可以一起用二者互斥只用其一用户不在会中先生成 OBFOBF 要求用户在场实现 5.5 节的重试逻辑用开发凭据跑外部会议开发凭据只能作用于自己账号申请生产凭据约 4–6 周审核九、时间线与权限范围汇总认证规则的时间线原文档日期变化当前JWT 签名必需ZAK 可选2025 年 11 月SDK v6.6.10 引入 OBF 专用错误码2026 年 2 月 23 日外部会议必须提供 OBF 或 ZAKOAuth 权限范围汇总令牌所需 ScopeZAK 令牌user:read:zakOBF 令牌user:read:token十、延伸在仓库中继续深入围绕本主题仓库内还有一份完整的参考文档矩阵按需查阅即可构成闭环references/bot-authentication.md —— 本文主体机器人三类令牌详解references/authorization.md —— JWT 签名字段与短时效最佳实践references/signature-playbook.md —— join failed 的签名根因排查手册含 4003 错误与passWord大小写陷阱references/troubleshooting.md —— 通用问题与解法linux/SKILL.md —— Linux 无头机器人C的初始化、认证与 raw recording 权限链路general/use-cases/meeting-bots.md —— 会议机器人整体架构与REST 签发令牌 SDK 入会 云录制 webhook的技能编排oauth/references/granular-scopes.md ——user:read:zak、user:read:token等 scope 的完整清单。适用前提与限制本文所有结论均以仓库内 Zoom 插件的 meeting-sdk 参考文档为准其中 OBF 强制要求的时间点2026-02-23、SDK 错误码引入版本v6.6.10与生产凭据审核周期4–6 周均为文档所述的 Zoom 侧政策落地前建议以你所用 SDK 版本的实际行为为准本文代码示例为文档内给出的参考实现不构成对 Zoom API 契约的完整定义。【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →