JSSDK 配置与签名

服务端 API 更新于 2026-09-21 阅读 11

阅读指引:本篇是《开放平台服务端 API 指南》的第 8 部分。接口基础地址、通用约定与各接口请求限制,请先阅读《服务端 API 概览》。

11. JSSDK config 与受保护能力

JSSDK 已提供 readyerrorgetAuthCodeconfigcloseWindowchooseChatopenChatgetAuthCode/closeWindow 在 Bridge ready 后可直接调用;chooseChat/openChat 是受保护能力,必须先完成包含目标 JSAPI 的 config

生命周期 API 参数 触发时机
ready(callback) callback: () => void,必填 未调用 config 时,在 Bridge 初始化成功后触发;页面调用 config 时,在 Bridge 和 config 都成功后触发。应在其他 JSAPI 之前注册。
error(callback) callback: (error) => void,必填 Bridge 初始化或 config 失败时触发;error 对象结构见第 11.6 节。应与 ready 一起尽早注册。

适用客户端类别为 Android、iOS 和 PC;实际可用能力以平台交付的客户端及 SDK 版本为准。JSSDK 最低版本为 1.0.0,Bridge 最低版本为 1.0。能力调用前仍会按当前客户端版本检查支持情况。

11.1 应用后端获取 jsapi_ticket

POST /openapi/v1/jssdk/ticket

curl -X POST "${OPENAPI_BASE_URL}/openapi/v1/jssdk/ticket" \
  -H "Authorization: Bearer ${APP_ACCESS_TOKEN}"
{
  "ticket": "jst_mim_xxx",
  "expires_in": 7200
}
位置/字段 类型/格式 必填 含义、范围与单位
Header Authorization Bearer <app_access_token> 有效的 App access token;User access token 不可使用。
请求 body 该接口不接收 JSON 或表单参数。
ticket string 成功时 短期 JSSDK 签名密钥,只能保存在应用后端并按不透明字符串使用。
expires_in integer 成功时 从响应生成时刻起的剩余有效期,单位秒;最长通常为 7200 秒,也不会超过来源 App access token 的剩余有效期。

有效期充足时,同一应用重复调用会复用当前 ticket;临近过期时平台轮换 ticket,并在短暂过渡期内接受仍有效的上一张 ticket。应用后端应按 expires_in 缓存,不要为每个页面请求一次 ticket。响应带有 Cache-Control: no-storePragma: no-cache,失败时返回 JSON 业务码而不返回 ticket

请求体最大 1 MiB但不接收业务参数;同一应用与来源 IP 每分钟最多调用 60 次,并同时受来源 IP 每分钟 300 次的全局限制。

失败业务码 含义与处理
170104 App access token 无效、过期、已撤销或 Token 类型错误;重新获取应用 Token。
170103 应用不存在、未发布或当前不可用;联系管理员检查应用状态。
170108 请求频率超限;按限流窗口退避后重试。
170309 ticket 服务异常;记录排障信息并有限次数重试。

服务端专用app_secret、app access token 和 jsapi_ticket 都不能进入 H5、客户端包体、普通日志或错误响应。

11.2 应用后端计算签名

import crypto from "node:crypto"

const jsApis = [...new Set(["openChat"].map(v => v.trim()).filter(Boolean))].sort()
const signedUrl = pageUrl.trim().split("#")[0] // 保留 query 原顺序,不重编码
const canonical = `v=1&app_key=${appKey.trim()}` +
  `&js_api_list=${jsApis.join(",")}` +
  `&nonce=${nonce.trim()}&timestamp=${timestamp}&url=${signedUrl}`
const signature = crypto
  .createHmac("sha256", jsapiTicket)
  .update(Buffer.from(canonical, "utf8"))
  .digest("hex")

签名字符串必须严格按示例字段名和顺序构造,UTF-8 编码,字段值不额外 URL 编码,末尾不加换行。jsApiList 先 trim、去空、去重,再按区分大小写的字符串升序排序并用英文逗号连接;URL 只去掉 fragment,必须保留 query 的原值和顺序。

11.3 H5 调用 config

im.openPlatform.ready(() => {
  // config 成功且 Bridge ready 后触发。
})

im.openPlatform.error(err => console.error(err.code, err.message))

await im.openPlatform.config({
  appKey: "svc_app_xxx",
  timestamp: 1787366400000,
  nonce: "nonce_20260822_001",
  signature: "b4be79f21080926eb10e7c3f81a50090a897a2731a10ccfbf9cf9d18a2389e2c",
  url: location.href.split("#")[0],
  jsApiList: ["openChat"]
})
参数 JavaScript 类型 必填 含义、范围与单位
appKey string 应用公开标识,与获取 App access token 时使用的 app_key 相同。
timestamp number 应用后端生成签名时的 Unix 毫秒时间戳;平台只接受服务器当前时间前后各 5 分钟。
nonce string 应用后端生成的随机串,trim 后非空且最长 128 字节;签名认证成功后同一应用不能重放相同 nonce。
signature string 应用后端使用当前 jsapi_ticket 计算的 64 位小写 hex HMAC-SHA256。
url string 参与签名的当前页面主 Frame URL;使用 location.href.split("#")[0],保留 query 及其顺序,并确保签名值与调用 config 时的页面 URL 完全一致。
jsApiList string[] 本页需要启用且要求 config 的 JSAPI;已登记 openChatchooseChat。任一名称未知、未授权或不要求 config 时,整个 config 失败。

chooseChat 用于选择用户会话列表,选择数量由用户自行决定;对应应用权限默认授予,当前状态为可用。调用前须完成 ready/config,获得 chat:conversation:choose,并由已登录用户的点击触发。该选择器由客户端 SDK 提供;具体入参和返回对象须使用平台交付 SDK 的类型定义,不得自行假设返回字段或用组织用户 ID 代替会话 ID。

config 成功后,本页只能调用 jsApiList 中已批准的受保护 JSAPI。配置过期、页面 URL 变化或应用权限变化后,应重新取得签名并调用 config;具体能力仍会校验当前用户的资源访问权和必要的用户手势。

JSSDK config 用于启用客户端能力,不应当作应用后端的用户登录凭据或业务授权证明。后端识别当前用户时须完成 OAuth2 换码并验证用户 Token 对应的身份,不能信任 H5 自报的用户信息。

11.4 closeWindow

await im.openPlatform.closeWindow()

closeWindow() 无参数,需要 Bridge ready,不需要 config、Scope 或用户登录上下文。Promise resolve 表示关闭请求已由容器接受;它只能关闭当前应用 WebView,不能指定或关闭其他窗口。

11.5 openChat

await im.openPlatform.openChat({
  conversationId: "conversation_xxx"
})

// 只打开当前用户有权访问的会话;不读取消息,也不代替用户发送消息。
参数/结果 类型 必填 说明
conversationId string 需要打开的会话不透明标识;不得解析、枚举或用其他类型的 ID 替代。
用户手势 运行条件 必须由用户本次点击等可信交互直接触发,不能在定时器、页面加载或后台回调中自动调用。
Promise resolve void 成功时 表示客户端已接受并完成会话导航,不返回消息内容或成员资料。

调用前必须满足:Bridge ready;当前 config 尚未过期且 jsApiList 包含 openChat;管理员已授予 chat:conversation:open;当前登录用户仍有权访问目标会话。每次调用都会重新检查用户手势和会话访问权。

11.6 统一 JSSDK 错误

所有返回 Promise 的 JSAPI 失败时 reject 以下对象;Bridge 初始化或 config 失败还会触发通过 error(callback) 注册的回调。

字段 类型 必填 说明
code string 稳定的机器可读错误码;应用应据此分支处理。
message string 面向开发排障的简短英文说明,不保证长期逐字不变,不应直接展示给最终用户。
requestId string 存在服务端调用时的排障请求标识;纯本地失败可能省略。
details object 非敏感补充信息;字段可扩展,业务逻辑不得依赖未文档化成员。
code 含义与建议处理
SDK_NOT_READY Bridge 尚未 ready;等待 ready 回调后再调用。
UNSUPPORTED_ENVIRONMENT / BRIDGE_VERSION_UNSUPPORTED 不在受支持的应用容器中或客户端版本过低;提示用户升级或在受支持客户端打开。
CONFIG_REQUIRED / CONFIG_EXPIRED / JSAPI_NOT_CONFIGURED 缺少有效 config;重新获取签名并 config,确保列表包含目标 JSAPI。
CONFIG_INVALID / INVALID_SIGNATURE / UNTRUSTED_URL 参数、签名、nonce、时间或页面 URL 不匹配;重新生成整组参数,不复用旧 nonce。
JSAPI_NOT_FOUND / JSAPI_NOT_SUPPORTED 名称错误或当前客户端不支持;检查拼写和客户端版本。
JSAPI_PERMISSION_DENIED 应用缺少 Scope、状态不可用或能力未授权;联系管理员检查应用权限。
USER_NOT_AUTHENTICATED 当前容器没有有效登录用户;要求用户登录后重试。
USER_GESTURE_REQUIRED 调用不是由可信用户操作直接触发;移到点击事件处理函数中。
RESOURCE_ACCESS_DENIED / RESOURCE_NOT_FOUND 用户无权访问目标资源,或资源不存在/不可见;不要循环重试。
USER_CANCELLED / SYSTEM_PERMISSION_DENIED 用户取消或拒绝系统权限;尊重用户选择并允许稍后主动重试。
INTERNAL_ERROR 客户端或服务端异常;记录 requestId 并有限次数重试。