
Zoom Cobrowse SDK JWT 认证实战在 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-pluginsCobrowse协同浏览会话中客户与客服代理都必须持有 JWT 才能鉴权接入 Zoom 的实时会话。本指南以 concepts/jwt-authentication.md 为核心骨架完整讲解如何在服务端用 SDK Key 与 SDK Secret 生成 Cobrowse JWT、如何为role_type1客户与role_type2代理签发不同令牌以及如何搭建生产可用的令牌服务端点。读完本文你将能独立实现一套安全合规的 JWT 签发与校验流程并理解令牌中每个 claim 的确切含义与约束。1. 为什么 JWT 必须由服务端签发Zoom Cobrowse 会话的鉴权基于 JWTJSON Web Token其签名算法为 HS256签名密钥是你在 Zoom 开发者后台获取的SDK Secret。这份凭据的保密等级直接决定整套认证体系是否安全。在 SKILL.md 的凭据总览中Cobrowse SDK 一共涉及 4 个凭据它们的暴露范围完全不同凭据类型用途可否暴露在客户端SDK Key公开出现在 CDN 加载 URL 与 JWT 的app_keyclaim 中✅ 可以本就会被浏览器看到SDK Secret私密用于 JWT 签名❌ 绝对不可以API Key私密REST API 鉴权可选❌ 不可以API Secret私密REST API 鉴权可选❌ 不可以核心结论有两点SDK Key 是公开的它会被内嵌进客户页面的 CDN 加载地址例如https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js/2.13.2因此可以被前端看到SDK Secret 必须永远留在服务端一旦泄露任何人都能以任意role_type伪造令牌、冒充客户或代理进入会话。因此jwt-authentication.md 将“用 SDK Key 与 SDK Secret 在服务端生成 Cobrowse JWT”作为首要指导原则。对应地get-started.md 在配置令牌服务时明确强调JWT 签名必须在服务端完成以保护 SDK Secret。错误与正确的做法对比摘自 SKILL.md// ❌ 错误SDK Secret 暴露在前端代码中 const jwt signJWT(payload, YOUR_SDK_SECRET); // 安全风险 // ✅ 正确Secret 留在服务端前端只向自己的后端请求令牌 const response await fetch(/api/token, { method: POST, body: JSON.stringify({ role: 1, userId, userName }) }); const { token } await response.json();2. JWT 结构Header 与 Payload 全字段说明所有 Cobrowse JWT 使用相同的 Header{ alg: HS256, typ: JWT }签名方式在 get-started.md 中有明确说明——使用 SDK Secret不是API Secret对base64UrlEncode(header) . base64UrlEncode(payload)做 HMAC-SHA256HMACSHA256( base64UrlEncode(header) . base64UrlEncode(payload), ZOOM_SDK_SECRET );2.1 Payload 字段表Payload 中的 claim 及约束如下综合 authorization-official.md 与 get-started.md 两张权威表Claim必填类型说明app_key✅string你的 Zoom SDK Key不是API Key用于客户与代理的 JWTrole_type✅number用户角色1 客户customer2 代理agentiat✅number令牌签发时间戳epoch 秒exp✅number令牌过期时间戳epoch 秒。最小 30 分钟最大 48 小时user_id✅string唯一可识别的用户 IDuser_name✅string用户名最长 80 个字符enable_byop可选number启用 BYOPBring Your Own PIN自带 PIN1 启用0或不传 关闭其中exp的时间窗口约束最小 30 分钟、最大 48 小时与user_name的 80 字符上限是实现令牌服务时必须校验的硬性边界。2.2 严格 claim 命名重点authorization-official.md 特别强调Cobrowse 令牌校验是严格的必须使用以下确切 claim 名称user_id不是user_identityapp_keyrole_typeuser_nameiatexp除非 Zoom 官方文档明确支持否则不要添加任何未被认可的扩展 claim。如果收到Invalid token错误码124应首先核对 claim 名称是否正确。3. 双角色模型为客户与代理分别签发令牌Cobrowse 会话中存在两个完全不同的角色详见 concepts/two-roles-pattern.md角色role_type值含义客户 Customer1主动分享自己浏览器画面的一方代理 Agent2查看会话并提供支持的服务人员jwt-authentication.md 提出的三条安全准则之一就是“为客户和代理角色生成不同的令牌”——即使同一用户在不同时间点切换身份也不应复用令牌。两角色使用同一套 JWT 认证模式但负载内容因角色而异。3.1 客户令牌示例role_type1const customerPayload { user_id: customer_123, app_key: YOUR_SDK_KEY, role_type: 1, user_name: John Customer, iat: Math.floor(Date.now() / 1000), exp: Math.floor(Date.now() / 1000) 3600 }; const token jwt.sign(customerPayload, SDK_SECRET, { algorithm: HS256 });3.2 代理令牌示例role_type2const agentPayload { user_id: agent_456, app_key: YOUR_SDK_KEY, role_type: 2, user_name: Support Agent, iat: Math.floor(Date.now() / 1000), exp: Math.floor(Date.now() / 1000) 3600 }; const token jwt.sign(agentPayload, SDK_SECRET, { algorithm: HS256 });两份示例均来自 references/authorization-official.md过期时间统一为签发后 1 小时3600 秒符合“短时令牌”的要求。4. 搭建令牌服务从零到可上线的端点4.1 可复用的签发函数将签发逻辑封装为单一函数references/get-started-official.md 给出了 Node.js 参考实现const jwt require(jsonwebtoken); function generateCobrowseToken(userId, userName, roleType) { const iat Math.floor(Date.now() / 1000); const exp iat 3600; // 1 小时 const payload { user_id: userId, app_key: SDK_KEY, role_type: roleType, // 1 customer, 2 agent user_name: userName, iat: iat, exp: exp }; return jwt.sign(payload, SDK_SECRET, { algorithm: HS256 }); }注意SDK_KEY与SDK_SECRET应来自服务端环境变量不要硬编码进代码。4.2 令牌请求 / 响应契约get-started.md 定义了令牌服务的统一 HTTP 契约——前端客户页与代理页通过 POST 请求携带角色信息换取 JWT// POST https://YOUR_TOKEN_SERVICE_BASE_URL { role: 1, // 1 customer, 2 agent userId: user123, userName: John Doe } // 响应 { token: eyJhbGciOiJIUzI1NiIs... }4.3 官方参考实现与本仓库的端点拆分建议官方提供了可克隆的令牌端点样例项目zoom/cobrowsesdk-auth-endpoint-sample其典型启动流程是克隆 →npm install→ 写入.env含ZOOM_SDK_KEY、ZOOM_SDK_SECRET、PORT→npm start服务将运行在你为令牌服务配置的 base URL 上。在此基础上concepts/two-roles-pattern.md 给出了更贴合业务的后端端点拆分建议将“签发令牌”与“会话管理”职责分离POST /api/customer/start→ 创建会话记录 签发客户令牌 生成 PINPOST /api/agent/connect→ 校验 PIN 签发代理令牌POST /api/session/revoke→ 结束会话GET /api/session/list→ 运营可见性查询会话状态其中代理令牌只有在 PIN 校验通过后才签发这从流程上保证了代理无法绕过 PIN 直接获取入场凭证。5. 安全准则三条不可妥协的红线jwt-authentication.md 在开篇即列出三条安全准则结合 references/authorization-official.md 的 Security 章节可以归纳为以下实现清单SDK Secret 绝不暴露在客户端前端代码、CDN 资源、浏览器 DevTools 中都不能出现 SDK Secret只有 SDK Key 允许出现在前端CDN URL 与app_keyclaim。签发短时令牌short-lived tokensexp的合法区间为 30 分钟到 48 小时官方示例普遍采用 1 小时短生命周期可最小化令牌泄露后的被利用窗口。不同角色使用不同令牌客户令牌role_type1与代理令牌role_type2分开生成永不混用令牌签发只发生在服务端客户端一律通过令牌服务接口获取。此外references/authorization-official.md 建议为exp设置合理的过期时间避免因过长有效期放大泄密风险。6. 令牌在完整会话流程中的位置JWT 不是孤立存在的它嵌入在 concepts/session-lifecycle.md 描述的完整流程中在客户页与代理页分别初始化 SDK服务端按角色生成 JWT 令牌客户发起会话并收到 PIN代理使用 PIN 加入会话会话事件跟踪 connected / disconnected / end 状态。典型的客户发起型会话get-started.md 的“客户 JWT 流程”中令牌的具体走向为客户侧前端 POST{role: 1, userId, userName}到令牌服务 → 拿到客户 JWT →session.start({ sdkToken: token })启动会话代理侧前端 POST{role: 2, userId, userName}到令牌服务 → 拿到代理 JWT → 将令牌拼入 Zoom 托管坐席台的 iframe 地址https://us01-zcb.zoom.us/sdkapi/zcb/frame-templates/desk?access_token${token}代理再输入客户 PIN 完成连接。6.1 一个容易踩的坑PIN 的唯一来源在令牌与会话管理对接时concepts/two-roles-pattern.md 强调交付给代理使用的 PIN必须是客户 SDK 事件session.on(pincode_updated, ...)发出的值而不是后端预启动占位记录中的临时 PIN。UI 中只展示一个明确标注的 PIN例如 “Support PIN”并在代理链接中复用同一个值。如果忽略此规则代理坐席台常会以Pincode is not found错误码30308失败。6.2 需要创建的服务端对象按 concepts/two-roles-pattern.md真实实现中通常按顺序创建以下对象客户会话记录服务端包含session_id、生成的 PIN、状态active/revoked、过期时间戳客户令牌role_type1供客户浏览器 SDK 启动/分享会话代理令牌role_type2在 PIN 校验通过后签发用于加载代理坐席 iframe 或自定义代理 UI。7. 常见故障与排查建议结合 references/authorization-official.md 与 get-started.md 的测试与排障章节JWT 相关的常见问题可按以下顺序排查症状优先检查项Invalid token错误码124先核对 claim 名称user_id而非user_identity、app_key、role_type、user_name、iat、exp是否拼写完全一致再检查是否添加了未被官方文档支持的扩展 claim令牌被服务端拒绝确认签名使用的是 SDK Secret 而非 API Secret确认app_key是 SDK Key 而非 API Key令牌频繁失效检查exp是否落在 30 分钟 ~ 48 小时的合法区间内时钟是否与 NTP 对齐代理无法连接确认使用的是pincode_updated事件中的真实 PIN且会话仍处于 active 状态确认页面使用 HTTPS仅 loopback/本地开发允许 HTTP8. 进一步阅读本文对应的仓库文档体系如下可继续深入概念文档concepts/jwt-authentication.md、concepts/two-roles-pattern.md、concepts/session-lifecycle.md权威参考references/authorization-official.md、references/get-started-official.md完整实操get-started.md含从凭据获取到首个会话的完整步骤技能入口与凭据总览SKILL.md掌握本节内容后你便拥有了一套安全、可复用的 Zoom Cobrowse SDK JWT 认证实现服务端独享 SDK Secret、按角色签发短时令牌、严格遵循官方 claim 命名并与 PIN 驱动的会话生命周期无缝衔接。【免费下载链接】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),仅供参考