Go Server SDK
官方 Go 伺服器端 SDK — github.com/Captcha-La/captchala-go。
SDK 為您處理三項任務:
- 驗證(Validate) — 校驗來自瀏覽器 SDK 的
pt_pass token。 - 簽發(Issue) — 簽發一次性
sct_server token,將即將發起的 challenge 綁定到特定 action / IP / UID。 - 內容審核(Moderate) — 多模態(文字 + 圖片)內容審核,與控制台共用同一條 OpenAI 相容管線。
安裝
bash
go get github.com/Captcha-La/captchala-go僅使用標準函式庫,無外部相依。
驗證(pt_ token)
請傳入終端使用者的 IP(從 CF-Connecting-IP / X-Forwarded-For 取得, 並回退至 RemoteAddr)。為選填,但建議帶上 — 它會用於額外的風險檢查。
go
import captchala "github.com/Captcha-La/captchala-go"
client := captchala.NewClient(appKey, appSecret)
func handler(w http.ResponseWriter, r *http.Request) {
token := r.FormValue("captcha_token")
result, err := client.ValidateWithClientIP(token, false, clientIP(r))
if err != nil || !result.Valid {
http.Error(w, result.Error, http.StatusBadRequest)
return
}
// Verification passed; proceed with the request.
// result.CaptchaArgs has Platform / UserIP / Referer / Pkg / SolvedAt / RiskScore
}
// Real end-user IP behind a CDN / proxy
func clientIP(r *http.Request) string {
if ip := r.Header.Get("CF-Connecting-IP"); ip != "" {
return ip
}
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
return strings.TrimSpace(strings.Split(xff, ",")[0])
}
host, _, _ := net.SplitHostPort(r.RemoteAddr)
return host
}手邊沒有 IP?改用 client.Validate(token) — 驗證照常運作,只是少了基於 IP 的額外風險訊號。
若原始 server_token 簽發時帶有 bind_uid,請進行比對:
go
if result.UID != expectedUserID {
http.Error(w, "user mismatch", http.StatusBadRequest)
return
}該次解題的環境資訊也會在 result.CaptchaArgs 中回傳,供您參考:
go
ip := result.CaptchaArgs.UserIP // visitor IP recorded at solve time簽發 server token
建議用於高價值流程(登入、註冊、支付):後端簽發一次性 sct_ token,交給瀏覽器,瀏覽器作為 serverToken prop 使用。 單次使用、限定 action,必要時可綁定 IP / UID。
go
issue, err := client.IssueServerTokenWithOptions("login", captchala.IssueOptions{
BindingIP: userIP, // backend rejects token if a different IP redeems it
TTL: 300, // seconds
MaxUses: 5, // SDK retry budget
BindUID: userID, // pair with ValidateResult.UID on verify
})
if err != nil || !issue.OK {
http.Error(w, issue.Error, http.StatusBadRequest)
return
}
// hand issue.Token to the browser僅使用預設值的快捷寫法:
go
issue, err := client.IssueServerToken("login")內容審核
多模態 — 接受 ModerationItem 切片(OpenAI 相容格式的 text 與/或 image_url):
go
result, err := client.ModerationCheck([]captchala.ModerationItem{
captchala.TextItem(userComment),
captchala.ImageURLItem(uploadedImageURL),
}, userID)
if err != nil || !result.OK {
http.Error(w, result.Error, http.StatusBadRequest)
return
}
if result.Flagged {
if result.HasCategory("violence", "csam") {
// hard block
}
}純文字快捷寫法:
go
result, err := client.ModerationText("user comment here", userID)分類由模型動態定義;請以遍歷 result.Categories 的方式防禦性處理,而非寫死固定集合。
型別
| 型別 | 欄位 |
|---|---|
ValidateResult | Valid、Error、UID、ChallengeID、Action、Offline、ClientOnly、Warning、CaptchaArgs |
CaptchaArgs(資訊性) | Platform、UserIP、Referer、Pkg、SolvedAt、RiskScore |
IssueResult | OK、Token、ExpiresIn、IssuedAt、Error、Message |
IssueOptions | BindingIP、TTL、MaxUses、BindUID |
ModerationItem | Type、Text、ImageURL(請使用 TextItem() / ImageURLItem() 輔助函式) |
ModerationResult | OK、Flagged、Categories、ContentType、Raw、Error、Message;方法 HasCategory(...names) |