Go Server SDK
公式の Go サーバーサイド SDK — github.com/Captcha-La/captchala-go。
SDK が引き受ける 3 つの役割:
- Validate — ブラウザ SDK が返した
pt_pass トークンを検証します。 - Issue — ワンタイムの
sct_server トークンを発行し、これから出す challenge を特定のアクション / IP / UID に紐付けます。 - Moderate — テキストと画像を含むマルチモーダルのコンテンツモデレーション。ダッシュボードと同じ OpenAI 互換パイプラインを使用します。
インストール
bash
go get github.com/Captcha-La/captchala-go標準ライブラリのみ。外部依存はありません。
Validate(pt_ トークン)
エンドユーザーの 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 timeserver トークンの発行
ログイン・新規登録・決済などの重要フローで推奨される方式です。バックエンドがワンタイムの sct_ トークンを発行し、ブラウザに渡し、ブラウザはそれを serverToken prop として使います。単回使用・アクションスコープで、必要に応じて IP / UID にバインドできます。
go
issue, err := client.IssueServerTokenWithOptions("login", captchala.IssueOptions{
BindingIP: userIP, // 別の IP がそのトークンを使おうとするとバックエンドが拒否する
TTL: 300, // 秒
MaxUses: 5, // SDK 側の再試行回数
BindUID: userID, // 検証時に ValidateResult.UID と突き合わせる
})
if err != nil || !issue.OK {
http.Error(w, issue.Error, http.StatusBadRequest)
return
}
// issue.Token をブラウザに渡すデフォルト設定のみのショートカット:
go
issue, err := client.IssueServerToken("login")コンテンツモデレーション
マルチモーダル — ModerationItem(OpenAI 互換のテキストおよび/または 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") {
// ハードブロック
}
}プレーンテキスト向けショートカット:
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) |