機器人

商品頁的 GET,本來就是「給全世界看的」,不能靠「有沒有權限」來擋,只能靠「你打得像不像正常逛商品的人」來擋
GET /products/12345
- 不需要登入
- 不需要 token
- 不需要 cookie
- 瀏覽器、爬蟲、搜尋引擎都合法
你不能直接說「你沒資格看」!

GET 天然就適合「狂打」,他無副作用、可被 cache、可被大量併發、可被簡單 script / curl / bot net 發送
不可能直接擋 GET,因為擋太嚴造成真實使用者 + SEO 都死光,而擋太鬆會被刷爆
商品頁 GET 一定要「設計成被打也不痛」

商品頁應該要有這些東西
- CDN cache
- HTML / JSON 都可快取
- Cache Key 控制好(shopId / productId)
所以機器人打的是 CDN,不是你後端

假如每個商品頁都 GET 商品頁 → 查商品 → 查庫存 → 查促銷 → 查會員 → 查推薦,會變得很可怕負擔很重,因此會將需要的層級拆分出來
- 商品基本資料:可 cache(秒~分鐘)
- 即時庫存:獨立 API(必要時才打)
- 個人化:登入後才載

不是「封鎖」,而是同 IP 同商品的每秒上限,超過就 429 或者是延遲回應,注意不要用全站 IP limit,用「IP + Path + ProductId」

機器人常見行為是只打 /products/12345,不換頁、不滑動、不加購物車,而人類通常會有 path 多樣性

登入系統不是在「擋正常使用者」,而是在用最小的摩擦成本,持續消耗攻擊者的時間與資源,讓攻擊變得不划算

Rate Limiting(請求次數限制)
同一個 IP、同一個帳號、同一段時間,只能嘗試有限次
CAPTCHA

CAPTCHA 不是用來保護系統,是用來讓攻擊者開始「覺得煩」
像是 Google reCAPTCHA、Cloudflare Turnstile(較不擾民)只在「可疑時」出現,不要每次都跳,判斷時機是
- 登入失敗 3 次以上
- 同 IP 大量請求
- 新裝置登入

密碼錯誤訊息不要太誠實

「此帳號不存在」
「密碼錯誤」
✅ 正確做法
「帳號或密碼錯誤」

Email / Phone 驗證
註冊後一定要驗證 Email,沒驗證不能使用完整功能
這是在呼叫端識別層(Identify the Caller)上下功夫,每個合作對象(App、系統)都發一組專屬 ClientId + Secret,所有請求都必須帶上這組憑證(例如放在 Header:X-Api-Key),可以細分權限:例如「查活動清單」與「修改活動」是不同授權





