← 返回目录
📁 Organic API › Accounts API › Guides › Webhooks

Webhook 验证

本文概述了如何进行 webhook 验证。

检查签名

TikTok webhook 随签名一起发送,目标服务器可使用此签名验证相关事件来自 TikTok 而非第三方或恶意系统。

强烈建议 webhook 用户在处理各个 webhook 事件前先验证这些签名。

验证信息签名

为保护您的应用程序免受中间人攻击和重放攻击,请验证发送至您应用的信息签名。Webhook 发送时间戳和 webhook 请求正文都是已签名的有效负载的一部分,因此,如果攻击者无法使签名失效,就不能更改时间戳。如果签名有效但时间戳过期,那么可以让您的应用程序拒绝有效负载。

签名作为 TikTok-Signature的header包含在 webhook 请求中。

TikTok-Signature 示例

(code curl http)
"Tiktok-Signature": "t=1633174587,s=18494715036ac4416a1d0a673871a2edbcfc94d94bd88ccd2c5ec9b3425afe66"
(/code)

签名验证

步骤 1:从header提取时间戳和签名

用,字符作分隔符拆分Tiktok-Signature 的header,获取元素列表。然后用=字符作分隔符拆分每个元素,获取键值对。

t 键的值对应以秒为单位的 Unix 时间戳,s 键对应在发送 webhook 时 TikTok 平台生成的签名。

步骤 2:生成签名

要生成签名并与已收到的签名进行对比的信息,可通过连接以下内容创建:

  • 已接收的时间戳字符串
  • '.'字符
  • 转换成JSON 字符串的请求body

创建完成后,将( API for Business 开发者门户网站为应用配置的)应用密钥作为键,使用 SHA256 散列函数计算 HMAC(基于散列的消息身份验证代码)。然后对已生成的 HMAC 进行十六进制编码,以便与已收到的签名进行对比。

步骤 3:签名对比

将header中的签名与已生成的签名进行对比。如果二者匹配,计算当前以秒为单位的 Unix 时间戳与header中已收到的时间戳之间的差值,以此确定差异是否在您的容差范围内。

运行示例

Node

(code curl http)
var CryptoJS = require("crypto-js");

// Example serialized copy of the webhook request to verify
const webhookRequest = {
  headers: {
    "host": "enj1gzfy7ltvrqf.m.pipedream.net",
    "x-amzn-trace-id": "Root=1-61de8b6a-1c7695005636528b40cac95f",
    "content-length": "251",
    "user-agent": "tiktok-webhook",
    "content-type": "application/json;charset=UTF-8",
    "tiktok-signature": "t=1641974633,s=dc023ece112b3a07d809896fd929928a132168d95d2a2e43aab0105fbb291df8",
    "webhook-schema-version": "v1.0",
    "x-tt-logid": "202201120803530102451591650189C78",
    "x-envoy-return-response-flags": "1",
    "rpc-persist-ori-path": "/"
  },
  body: {
    client_key: "7043848340043202562",
    event: "share.video.publish_complete",
    create_time: 1641974632,
    user_openid: "a81e31c6-3b57-40d7-9253-c2f211e70514",
    content: "{\"share_id\":\"v_publish.7052073813521844225\",\"video_id\":\"7044071604573310209\"}"
  }
};

// Replace your signing key (app secret) and acceptable webhook delay in seconds
const signingKey = "****************************************";
const acceptableDelay = 5;

// Collect the necessary information for webhook validation
const body = JSON.stringify(webhookRequest.body);
const keys = webhookRequest.headers["tiktok-signature"].split(',');
const receivedTimestamp = keys[0].split("=")[1];
const receivedSignature = keys[1].split("=")[1];

// Function to validate incoming webhook signature
function validateSignature (receivedTimestamp, receivedSignature, body) {
  // Create signed payload, generate HMAC, hex encode the HMAC
  const signedPayload = receivedTimestamp + '.' + body;
  const hmac = CryptoJS.HmacSHA256(signedPayload, signingKey);
  const computedSignature = CryptoJS.enc.Hex.stringify(hmac); 

  // If computed and received signatures match
  if (computedSignature === receivedSignature) {
    // Check if current timestamp within acceptable delay from received timestamp
    const currentTimestamp = Math.round(new Date().getTime() / 1000);
    const delay = currentTimestamp - receivedTimestamp;

    if (delay <= acceptableDelay) return true;
    else return false;
  }
  else return false;
};

if (validateSignature(receivedTimestamp, receivedSignature, body)) {
  // return a 200 HTTP response and continue with webhook processing
}
else {
  // return a 4xx HTTP response status and raise a verification exception
  // log the x-tt-logid header
}
(/code)

内容来源:TikTok API for Business 官方文档 · 本地归档

在接这个接口时卡住了?
Stuck wiring this API into production? We build ad-delivery tooling on these platforms — campaign automation, reporting pipelines, error-handling and migration between API versions.
联系我们 · Talk to us 每日平台更新简报 →