文件 v1.0.0

請求流程

本頁說明 IPGuardian.Check 對單一請求的判定順序,以及每一步回傳的狀態碼與錯誤訊息。

判定順序

graph TB
    A[getDevice] -->|失敗| E500[500 Failed to get device info]
    A --> T{Trust?}
    T -->|是| OK[200]
    T -->|否| B{Block?}
    B -->|是| F1[403 Device is blocked]
    B -->|否| N{Ban?}
    N -->|是| F2[403 Device is banned]
    N -->|否| S[dynamicScore]
    S -->|分數 >= 100| F3[403 Device is blocked]
    S --> RL{速率限制}
    RL -->|超限| F4[403 rate limit]
    RL -->|未超限| OK
步驟 條件 結果
1 無法解析 IP 或簽發 Session 500,Failed to get device info
2 IP 在 Allow 名單 200,跳過後續所有步驟
3 IP 處於 Block 期間 403,Device is blocked, IP: {ip}
4 IP 在 Deny 名單 403,Device is banned, IP: {ip}
5 四維評分總分 >= 100 403,Device is blocked, IP: {ip}
6 分數 >= ScoreDangerous 且每分鐘請求數 >= RateLimitDangerous 403,... rate limit (Dangerous) ...
7 分數 >= ScoreSuspicious 且每分鐘請求數 >= RateLimitSuspicious 403,... rate limit (Suspicious) ...
8 每分鐘請求數 >= RateLimitNormal 403,... rate limit (Normal) ...
9 以上皆未命中 200

每次 Check 都會發生的副作用

getDevice 在名單判定之前就執行,因此即使請求最後被拒絕:

副作用 說明
frequency:{ip}:{minute} 加 1 每分鐘請求計數;以 Unix 分鐘切窗,不是滑動視窗
寫入兩個 Set-Cookie conn.sess.id 與 conn.device.id,每次都刷新有效期
block:count:{ip} 加 1 只在 IP 處於 Block 期間

評分步驟另外會寫入各維度的 Redis 集合與列表,見 Redis Key。

速率限制的實際上限

計數包含當前請求且以 >= 比較,所以設定值 N 代表同一分鐘最多放行 N - 1 個請求。以預設值為例:

分級 設定 同一分鐘可通過
Normal 100 99
Suspicious 50 49
Dangerous 20 19

視窗以 Unix 時間的整分鐘切割,跨分鐘邊界時計數歸零,短時間內最多可通過約兩倍上限。

錯誤處理邊界

情境 行為
Redis 在評分階段失敗 dynamicScore 回傳 nil 與錯誤,Check 只記錄錯誤後讀取 score.IsBlock,造成 nil pointer panic,見 已知問題
Allow/Deny 查詢 Redis 失敗 回退記憶體快取
Block 查詢 Redis 失敗 視為未封鎖(fail-open)
每分鐘計數失敗 計數視為 1

回應格式

Check 回傳 IPGuardianResult;兩個中介層把失敗結果轉成 JSON:

{"error": "Device is banned, IP: 198.51.100.77"}

自行呼叫 Check 的寫法見 中介層。

EN