Skip to content

广告反作弊

这是一份场景指南。核心接入不变——你照常加载 Web SDK、读取 裁决,并从数据 API 拉取数据,和那几页里描述的 完全一样。本页只补充广告反作弊场景特有的那一点内容。

广告反作弊把机器人与无效流量挡在付费投放之外,让广告主与广告平台为真实的点击和展示 付费——而非虚假量。它与其它使用场景的不同之处在于:访客由第三方送来,且双方需要 就一份独立的、逐点击的真人/机器人结论达成一致。

源头实时拦截

反欺诈在入口处 inline 运行、实时给出裁决——它不是事后报表。访客落在谁的页面上,谁就能立刻据裁决处置:

  • 广告主在落地页跑 SDK:无效流量一到达就被识别——并可选触发验证码——在它进入转化漏斗、污染报表之前就拦住。
  • 流量平台在自己的 pre-lander 或跳转页跑 SDK:点击在被转发之前就先验一道,机器人在入口就被拦下,根本不会变成已投递流量。

唯一前提是要有一张能跑 SDK 的页:裁决需要浏览器信号,纯服务端 302 跳转没有采集信号的地方——加一个极轻的中间页,同样能实时拦截。

签名 click token 与数据 API 在此之上做两端对账;实时 inline 拦截是主要机制,事后 API 清洗是没有中间页时的兜底。

两端角色

  • 广告主(Advertiser) —— 拥有访客落地的页面。在该页面上运行 Web SDK,为每次到达的 访问拿一份裁决,并从数据 API 拉取裁决,以核对自己被计费的部分。
  • 服务商(Provider,流量/广告来源) —— 投递点击。它需要证明自己投递的质量, 因此为每次点击签发一个点击 token,之后用独立裁决去比对自己的投递报表。

双方都用各自的应用凭据向数据 API 鉴权,并读取同一份逐点击裁决——正是 这一点让他们无需互信对方的原始日志即可对账。

端到端流程

下面的时序图展示了一次点击如何从服务商的投递,经访客与广告主落地页,最终落到同一份 裁决上——而两个账号之后各自从自己一侧读到这同一行

关键特性在于:两个 app_id 落在同一行上。 广告主按 advertiser_app_id 匹配读到它, 流量方按 provider_app_id 匹配读到它——两个不同账号,各用各自的 App-Key 查询,各自 落到同一份独立裁决上。双方无需暴露或互信对方的原始日志,即可就某次点击发生了什么 达成一致。

点击 token

**点击 token(click token)**把服务商投递的某次点击,与该次访问最终收到的裁决关联 起来。它是双方据以结算的逐点击标识。反欺诈的其它使用场景无需点击 token——不用它也能 对账裁决。

流程:

  1. 签发 —— 服务商在把访客路由到广告主落地页时,获取一个已签名的点击 token (每次点击一个)。

  2. 拼接到目标 URL —— 把签发的 token 作为查询参数拼到落地 URL 上:

    https://advertiser.example/lp?click_token=ct_xxxxxxxx
  3. 在页面读取 —— Web SDK 会自动从 URL 读取该 token。若你使用不同的 参数名,设置 tokenParam:

    js
    BotSignal.init({ appKey: 'YOUR_APP_KEY', tokenParam: 'click_token' });
  4. 对账 —— 之后通过数据 API 查回该点击,并与服务商的投递报表关联。

INFO

该 token 在签发给你时就已签名——你只需把它透传到落地 URL 即可。你这边无需做任何 签名或计算。

tokenParam 选项

在这个场景下,Web SDK 多出一个选项:

选项类型默认值说明
tokenParamstring自动识别URL 查询参数名,用于携带服务商的点击 token(如 click_token)。SDK 会从页面 URL 中读取它,并把裁决与该次点击关联。若不使用点击 token,保持默认即可。

对账与结算

一旦访问携带了点击 token,双方就基于同一份独立裁决结算:

  • 获取单次点击的裁决 —— 例如用于申诉或确认某次点击:

    bash
    GET /v1/bot/verdict?click_token=ct_xxx
    X-App-Key: YOUR_APP_KEY
    X-App-Secret: YOUR_APP_SECRET
  • 导出逐点击行 —— 拉取一个时间范围,把每行的 click_token 与你自己的点击日志关联:

    bash
    GET /v1/bot/export?from=2026-06-01&to=2026-06-30&format=csv
    X-App-Key: YOUR_APP_KEY
    X-App-Secret: YOUR_APP_SECRET

    每一行携带该次访问的 click_token(若存在)、时间戳,以及裁决字段 (is_botscorelevelaction)。

广告主把被标记和机器人点击从付费中剔除;服务商用同一份结论比对自己的投递报表。因为 双方读取的是同一份独立裁决,结算不依赖任何一方的原始日志。

安全模型

cid 与 click token 走在 URL 里,所以把它们当标识符、而不是凭证:

  • 读裁决必须 App-Key + App-Secret。 数据 API 每次调用都用你的 app secret 鉴权(常量时间比较),且只返回"你是其中广告主或流量方"的行。光有 cid 查不到任何东西——路人从 URL 抄走它,既没有 secret、也不是这行的任何一端。
  • 流量方由签名绑定。 click token 用流量方 secret 做 HMAC 签名、带流量方 pkid,无法伪造;同一 cid 只能被认领一次(防重放)。
  • 可选:把广告主也绑上。 把目标广告主的 app_key 作为 aud 签进 token。验证时要求页面的 app_key 与 aud 一致——这样发给广告主 A 的 token 就无法在广告主 B 身上归属裁决。不签 aud 则任意广告主页面都可承接。

最终效果:某个 cid 的裁决,只有钉在它上面的两个 app 能读——跑了 SDK 的那个广告主、出示了 token 的那个流量方,各自用自己的 App-Secret 鉴权。

下一步

MIT-licensed examples · CaptchaLa is operated independently