--- title: 反詐欺 — 廣告反作弊 --- # 廣告反作弊 這是一份**場景指南**。核心接入不變——你照常載入 [Web SDK](../web-sdk)、讀取 [裁決](../verdict-reference),並從[資料 API](../data-api) 拉取資料,和那幾頁裡描述的 完全一樣。本頁只補充廣告反作弊場景特有的那一點內容。 廣告反作弊把機器人與無效流量擋在付費投放之外,讓廣告主與廣告平台為真實的點擊和曝光 付費——而非虛假量。它與其他使用場景的不同之處在於:**訪客由第三方送來**,且雙方需要 就一份獨立的、逐點擊的真人/機器人結論達成一致。 ## 源頭即時攔截 反作弊在入口處 inline 執行、即時給出裁決——它不是事後報表。訪客著陸在誰的頁面上,誰就能立刻依裁決處置: - **廣告主**在著陸頁跑 SDK:無效流量一到達就被識別——並可選觸發驗證碼——在它進入轉換漏斗、污染報表之前就攔住。 - **流量平台**在自己的 pre-lander 或跳轉頁跑 SDK:點擊在**被轉發之前**就先驗一道,機器人在入口就被攔下,根本不會變成已投遞流量。 唯一前提是要有一張能跑 SDK 的頁:裁決需要瀏覽器訊號,純伺服器端 302 跳轉沒有採集訊號的地方——加一個極輕的中間頁,同樣能即時攔截。 簽名 click token 與資料 API 在此之上做兩端對帳;即時 inline 攔截是主要機制,事後 API 清洗是沒有中間頁時的兜底。 ## 兩端角色 - **廣告主(Advertiser)** —— 擁有訪客著陸的頁面。在該頁面上執行 Web SDK,為每次到達的 訪問拿一份裁決,並從資料 API 拉取裁決,以核對自己被計費的部分。 - **服務商(Provider,流量/廣告來源)** —— 投遞點擊。它需要**證明自己投遞的品質**, 因此為每次點擊簽發一個點擊 token,之後用獨立裁決去比對自己的投遞報表。 雙方都用各自的應用程式憑證向[資料 API](../data-api) 鑑權,並讀取同一份逐點擊裁決——正是 這一點讓他們無需互信對方的原始日誌即可對帳。 ## 端到端流程 下面的時序圖展示了一次點擊如何從服務商的投遞,經訪客與廣告主著陸頁,最終落到同一份 裁決上——而**兩個帳號之後各自從自己一側讀到這同一列**。 ```mermaid sequenceDiagram autonumber participant P as 流量方(Provider / 帳號 B) participant V as 訪客(Visitor) participant A as 廣告主著陸頁 + SDK participant F as 反詐欺後端(Fraud Prevention API) P->>P: 用自己的 bot_kid + secret 簽 click_token(內含 pkid) P->>V: 把 token 拼進投放連結 ?_ctk=click_token V->>A: 點擊 → 落到廣告主著陸頁(URL 攜帶 _ctk) A->>A: SDK 從 URL 讀取 _ctk A->>F: 加密 POST /bot/verify
(app_key = 廣告主,click_token = 服務商所簽) F->>F: app_key → advertiser_app_id,
驗簽 pkid → provider_app_id,出裁決,
一列寫入兩端 app_id F-->>A: verdict → onVerdict A->>A: 按 verdict.action 處理(記錄 / 攔截 / 彈驗證碼) Note over P,F: 對帳(跨帳號) A->>F: 廣告主用自己的 App-Key 查 GET /v1/bot F-->>A: 讀到同一列(匹配 advertiser_app_id) P->>F: 流量方用自己的 App-Key 查 GET /v1/bot F-->>P: 讀到同一列(匹配 provider_app_id) ``` 關鍵特性在於:**兩個 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](../web-sdk) 會自動從 URL 讀取該 token。若你使用不同的 參數名,設定 `tokenParam`: ```js BotSignal.init({ appKey: 'YOUR_APP_KEY', tokenParam: 'click_token' }); ``` 4. **對帳** —— 之後透過資料 API 查回該點擊,並與服務商的投遞報表關聯。 ::: info 該 token 在簽發給你時就已簽名——你只需把它**透傳到著陸 URL** 即可。你這邊無需做任何 簽名或計算。 ::: ### `tokenParam` 選項 在這個場景下,Web SDK 多出一個選項: | 選項 | 型別 | 預設值 | 說明 | | --- | --- | --- | --- | | `tokenParam` | string | 自動辨識 | 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_bot`、`score`、`level`、`action`)。 廣告主把被標記和機器人點擊從付費中剔除;服務商用同一份結論比對自己的投遞報表。因為 雙方讀取的是**同一份獨立裁決**,結算不依賴任何一方的原始日誌。 ## 安全模型 `cid` 與 click token 走在 URL 裡,所以把它們當**識別碼**、而不是**憑證**: - **讀裁決必須 App-Key + App-Secret。** Data 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 鑑權。 ## 下一步 - [Web SDK](../web-sdk) —— 在著陸頁收集裁決 - [裁決欄位參考](../verdict-reference) —— 每個欄位及處理方式 - [資料 API](../data-api) —— 伺服器端拉取與對帳裁決