Skip to content

Go-Server-SDK ​

Offizielles serverseitiges Go-SDK — github.com/Captcha-La/captchala-go.

Drei Aufgaben, die das SDK für Sie übernimmt:

  1. Validate — verifiziert einen pt_-Pass-Token aus dem Browser-SDK.
  2. Issue — stellt einen Einmal-sct_-Server-Token aus, um die anstehende Challenge an eine bestimmte action / IP / UID zu binden.
  3. Moderate — multimodale (Text + Bild) Content-Moderation gegen dieselbe OpenAI-kompatible Pipeline, die auch das Dashboard verwendet.

Installation ​

bash
go get github.com/Captcha-La/captchala-go

Ausschließlich Standardbibliothek. Keine externen Abhängigkeiten.

Validate (pt_-Token) ​

Übergeben Sie die IP des Endnutzers (aus CF-Connecting-IP / X-Forwarded-For, mit Rückfall auf RemoteAddr). Optional, aber empfohlen — sie wird für zusätzliche Risikoprüfungen verwendet.

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
}

Keine IP zur Hand? Verwenden Sie client.Validate(token) — die Verifizierung funktioniert weiterhin, nur ohne das zusätzliche IP-basierte Risikosignal.

Falls der ursprüngliche server_token mit bind_uid ausgestellt wurde, vergleichen Sie:

go
if result.UID != expectedUserID {
    http.Error(w, "user mismatch", http.StatusBadRequest)
    return
}

Der Kontext zum Lösungszeitpunkt wird zudem in result.CaptchaArgs zu Ihrer Referenz zurückgegeben:

go
ip := result.CaptchaArgs.UserIP   // zum Lösungszeitpunkt erfasste Besucher-IP

Reine Client-Tokens (Fallback bei Ausfall) ​

Ist die CaptchaLa-API nicht erreichbar, kann das Client-SDK die Challenge trotzdem abschließen und liefert ein reines Client-Token (Präfix client_ oder co_). Es wird nur akzeptiert, wenn die API auch von Ihrem Server aus nicht erreichbar ist; andernfalls wird es mit Error="client_only_rejected_api_reachable" abgelehnt. Ein akzeptiertes Token ist mit ClientOnly=true markiert.

Das Erreichbarkeitsergebnis wird zwischengespeichert (30 s bei erreichbar, 5 s bei nicht erreichbar), sodass ein Ausfall nicht jede Anfrage verlangsamt. Gleichzeitige Validierungen teilen sich eine Prüfung.

Für sensible Aktionen (Login, Zahlung) können Sie reine Client-Tokens auch während eines Ausfalls ablehnen:

go
client.RejectClientOnly = true
// client_ / co_ -> Valid=false, Error=captchala.ErrClientOnlyPolicy ("client_only_rejected_by_policy")

Server-Token ausstellen ​

Empfohlen für hochwertige Flows (Anmeldung, Registrierung, Bezahlung): Das Backend stellt einen Einmal-sct_-Token aus, übergibt ihn an den Browser, der Browser verwendet ihn als serverToken-Prop. Einmal-, action-bezogen, optional IP/UID-gebunden.

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

Abkürzung nur mit Standardwerten:

go
issue, err := client.IssueServerToken("login")

Inhalte moderieren ​

Multimodal — akzeptiert einen Slice von ModerationItem (Text und/oder image_url im OpenAI-kompatiblen Format):

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
    }
}

Reine-Text-Abkürzung:

go
result, err := client.ModerationText("user comment here", userID)

Kategorien werden vom Modell definiert; iterieren Sie result.Categories defensiv, statt einen festen Satz hart zu kodieren.

Typen ​

TypFelder
ValidateResultValid, Error, UID, ChallengeID, Action, Offline, ClientOnly, Warning, CaptchaArgs
CaptchaArgsPlatform, UserIP, Referer, Pkg, SolvedAt, RiskScore (rein informativ)
IssueResultOK, Token, ExpiresIn, IssuedAt, Error, Message
IssueOptionsBindingIP, TTL, MaxUses, BindUID
ModerationItemType, Text, ImageURL (Helper TextItem() / ImageURLItem() verwenden)
ModerationResultOK, Flagged, Categories, ContentType, Raw, Error, Message; Methode HasCategory(...names)

MIT-licensed examples · CaptchaLa is operated independently