跳至内容

鉴权与签名 ​

接入方调用开放接口使用 AppKey / AppSecret,采用 HMAC-SHA256 签名。不依赖控制台登录态或浏览器 Cookie。

请求头 ​

请求头说明
OC-App-Key当前工作空间的 AppKey
OC-TimestampUnix 毫秒时间戳,与平台时间相差不超过 5 分钟
OC-Nonce每次请求生成新的随机串,16~64 位,允许字母、数字、-、_
OC-Signaturev1= 加 HMAC-SHA256 的小写十六进制结果
X-Request-ID可选,请求排查标识,最长 64 位

AppSecret 只放在接入方服务端,不进入网页、移动端安装包或模型上下文。

签名内容 ​

使用换行符连接以下七行,末尾不加换行:

text
OC-HMAC-SHA256
{大写 HTTP 方法}
{原始请求路径}
{原始查询字符串,不含问号}
{OC-Timestamp}
{OC-Nonce}
{请求体 SHA-256,小写十六进制}

没有查询字符串时,第四行保留为空。路径和查询字符串按实际发送内容计算,不额外排序或解码。没有请求体时,对空字节串求摘要。

签名自检 ​

当前已有 GET /api/open/v1/auth/check 和 POST /api/open/v1/auth/check,可用于确认签名链路。开放接口域名由平台在联调时提供。

下面的 Node.js 示例只调用自检接口,不推送业务消息:

js
import { createHash, createHmac, randomBytes } from "node:crypto";

const { OMNICHAT_BASE_URL, OMNICHAT_APP_KEY, OMNICHAT_APP_SECRET } =
  process.env;
if (!OMNICHAT_BASE_URL || !OMNICHAT_APP_KEY || !OMNICHAT_APP_SECRET) {
  throw new Error("请在服务端配置域名、AppKey 与 AppSecret");
}
const url = new URL("/api/open/v1/auth/check", OMNICHAT_BASE_URL);
if (url.protocol !== "https:") throw new Error("开放接口须使用 HTTPS");
const body = JSON.stringify({ ping: "hello" });
const timestamp = String(Date.now());
const nonce = randomBytes(16).toString("hex");
const digest = createHash("sha256").update(body, "utf8").digest("hex");
const canonical = [
  "OC-HMAC-SHA256",
  "POST",
  url.pathname,
  url.search.slice(1),
  timestamp,
  nonce,
  digest,
].join("\n");
const signature = createHmac("sha256", OMNICHAT_APP_SECRET)
  .update(canonical, "utf8")
  .digest("hex");

const response = await fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "OC-App-Key": OMNICHAT_APP_KEY,
    "OC-Timestamp": timestamp,
    "OC-Nonce": nonce,
    "OC-Signature": `v1=${signature}`,
  },
  body,
  signal: AbortSignal.timeout(10000),
});
console.log(response.status, await response.text());

常见排查方向 ​

  • 签名不匹配:检查发送字节是否和计算摘要的请求体相同。
  • 请求过期:确认服务器时钟和毫秒时间戳。
  • 随机数重复:每次重试更换 nonce,并重新签名。
  • 空间不正确:确认使用的凭证属于目标空间,不通过请求体切换空间。

消息回调使用独立密钥,签名格式见消息回调。

错误与限流 ​

业务接口均为 POST JSON;签名自检另支持 GET。请求体最大 1 MB,默认每个 AppKey 每个自然分钟 600 次请求,部署可调。成功响应为 {"code":"OK","message":"success","data":{}};错误如下:

json
{ "code": "CONFLICT", "message": "请检查目前资源状态", "data": null }
HTTPcode处理方式
400INVALID_ARGUMENT修正字段或配置
401AUTH_REQUIRED / INVALID_CREDENTIALS检查凭证及签名
401REQUEST_EXPIRED校时并重新签名;OC-Server-Time 返回平台毫秒时间
401REQUEST_REPLAYED更换 nonce,重新签名;保留业务 eventId
403CREDENTIAL_DISABLED / FORBIDDEN检查空间、凭证状态及 IP 白名单
404NOT_FOUND先同步用户或核对角色识别
409CONFLICT / VERSION_CONFLICT查询目前数据,再决定修改或重试
413PAYLOAD_TOO_LARGE缩小请求体
429RATE_LIMITED退避后重新签名重试
503SERVICE_UNAVAILABLE暂时不可用,稍后重试

网络超时不代表请求未执行。聊天事件重试保持 eventId;角色创建/发布先查询确认结果,不要盲目重试。X-Request-ID 用于追踪,不提供业务去重。

可下载 Node.js 请求签名与回调验签示例,用法见快速开始。

OmniChat · 让交互自然发生