Skip to content

Go Server SDK

公式の Go サーバーサイド SDK — github.com/Captcha-La/captchala-go

SDK が引き受ける 3 つの役割:

  1. Validate — ブラウザ SDK が返した pt_ pass トークンを検証します。
  2. Issue — ワンタイムの sct_ server トークンを発行し、これから出す challenge を特定のアクション / IP / UID に紐付けます。
  3. 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_tokenbind_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 トークンの発行

ログイン・新規登録・決済などの重要フローで推奨される方式です。バックエンドがワンタイムの 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 をディフェンシブに走査してください。

フィールド
ValidateResultValidErrorUIDChallengeIDActionOfflineClientOnlyWarningCaptchaArgs
CaptchaArgs(情報用)PlatformUserIPRefererPkgSolvedAtRiskScore
IssueResultOKTokenExpiresInIssuedAtErrorMessage
IssueOptionsBindingIPTTLMaxUsesBindUID
ModerationItemTypeTextImageURLTextItem() / ImageURLItem() ヘルパーを使用)
ModerationResultOKFlaggedCategoriesContentTypeRawErrorMessage。メソッド HasCategory(...names)

リンク

MIT-licensed examples · CaptchaLa is operated independently