Skip to content

Session 撤銷回呼

平台 → 廠商回呼之一:這個方向相反,由平台呼叫你的伺服端,而不是你呼叫平台。這是運營商踢線能夠送達仍開啟中遊戲畫面的方式——為什麼會觸發、什麼時候觸發,見伺服端接入指南的「入站回呼」章節。

請實作 POST /v1/game/session/revoke(精確的路徑,位於你的對接窗口為你註冊的 baseUrl 上),並在信任請求內容之前,用 @moosehq/provider-sdkverifyPlatformSignature 驗證每一次呼叫——這次是平台在呼叫你,所以「SDK 幫我簽好名」這套慣例反過來了。

請求

簽名方式和你自己發出的請求一致:X-Tenant-IDX-TimestampX-NonceX-Signature 四個請求頭,用你的廠商密鑰對 method + "\n" + path + "\n" + timestamp + "\n" + nonce + "\n" + bodyHMAC-SHA256X-Tenant-ID 帶的是你自己的廠商租戶 ID(平台是在向你證明「這通呼叫是給你的」,不是在報自己的身份)。

請求體:

ts
type RevokeSessionRequest = {
  sessionToken: string
  playerRef: string
  gameId: string
  reason?: string // 例如 "operator kick"——可能為空
}

響應

成功請返回 200。任何其他狀態碼平台都只會記錄下來,不會重試,也不會改變踢線本身的結果——如前所述,session 無論如何都已經被刪除了。

範例(Node/Express)

ts
import { verifyPlatformSignature, type RevokeSessionRequest } from '@moosehq/provider-sdk'

// req.body 必須是平台簽名時用的那個原始字串本身,所以這個路由
// 需要原始 body,不能用 JSON 解析中介軟體。
app.post('/v1/game/session/revoke', express.text({ type: '*/*' }), (req, res) => {
  const result = verifyPlatformSignature({
    method: req.method,
    path: req.path,
    headers: req.headers,
    body: req.body,
    secret: process.env.PLATFORM_SECRET!,
    now: new Date(),
    expectedTenantId: 'acme-studio', // 你自己的廠商租戶 ID
  })
  if (!result.ok) return res.status(401).json({ error: result.reason })

  const revoke: RevokeSessionRequest = JSON.parse(req.body)
  // 在你這一側結束 revoke.sessionToken,並且——若是瀏覽器端遊戲——
  // 透過你自己的通道通知正在執行的客戶端(例如 game-client SDK 的
  // notifySessionRevoked),讓它立即退出,而不是等到下一次錢包呼叫收到 401。
  res.sendStatus(200)
})

verifyPlatformSignature

ts
function verifyPlatformSignature(input: VerifyPlatformSignatureInput): VerifyPlatformSignatureResult

type VerifyPlatformSignatureInput = {
  method: string
  path: string                 // 僅 URL 路徑——不含 scheme/host/query
  headers: IncomingHeaders     // 例如 Node 的 req.headers——小寫鍵名
  body: string                 // 平台簽名時所用的原始請求體字串
  secret: string               // 你的廠商密鑰
  now: Date
  maxSkewSeconds?: number      // 預設 300(5 分鐘)
  expectedTenantId?: string    // 選填的多一層防護檢查
}

type VerifyPlatformSignatureResult =
  | { ok: true; tenantId: string }
  | {
      ok: false
      reason:
        | 'missing-tenant-id'
        | 'tenant-id-mismatch'
        | 'missing-timestamp'
        | 'timestamp-skew'
        | 'missing-nonce'
        | 'invalid-signature'
    }

和平台自己的 HMACVerifier 不同,這個函式在密鑰輪替期間不會查詢「上一個密鑰」的寬限期——那是平台端按租戶處理的機制;廠商在驗證入站呼叫時,永遠只用自己當前唯一的密鑰做校驗。