跳至內容

鑑權與簽名 ​

接入方呼叫開放介面使用 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 · 讓互動自然發生