Skip to content

SDK de servidor Go

SDK oficial de Go para el servidor — github.com/Captcha-La/captchala-go.

Tres tareas que el SDK gestiona por ti:

  1. Validar — verifica un pass token pt_ del SDK del navegador.
  2. Emitir — genera un server token sct_ de un solo uso para vincular el próximo desafío a una acción / IP / UID concretas.
  3. Moderar — moderación de contenido multimodal (texto + imagen) contra la misma pipeline compatible con OpenAI que utiliza el panel.

Instalación

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

Solo stdlib. Sin dependencias externas.

Validar (token pt_)

Pasa la IP del usuario final (desde CF-Connecting-IP / X-Forwarded-For, con respaldo en RemoteAddr). Es opcional, pero recomendado: se usa para comprobaciones de riesgo adicionales.

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
}

¿No tienes la IP a mano? Usa client.Validate(token): igual verifica, solo que sin la señal de riesgo adicional basada en la IP.

Si el server_token original se emitió con bind_uid, compara:

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

El contexto del momento de la resolución también se devuelve en result.CaptchaArgs para tu referencia:

go
ip := result.CaptchaArgs.UserIP   // IP del visitante registrada en el momento de la resolución

Emitir un server token

Recomendado para flujos de alto valor (inicio de sesión, registro, pago): el backend genera un token sct_ de un solo uso, lo entrega al navegador y este lo usa como prop serverToken. Un solo uso, acotado a una acción y vinculable opcionalmente a 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

Atajo con valores por defecto:

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

Moderar contenido

Multimodal — acepta un slice de ModerationItem (texto y/o image_url en formato compatible con OpenAI):

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

Atajo de texto plano:

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

Las categorías las define el modelo; recorre result.Categories de forma defensiva en lugar de codificar un conjunto fijo.

Tipos

TipoCampos
ValidateResultValid, Error, UID, ChallengeID, Action, Offline, ClientOnly, Warning, CaptchaArgs
CaptchaArgsPlatform, UserIP, Referer, Pkg, SolvedAt, RiskScore (solo informativo)
IssueResultOK, Token, ExpiresIn, IssuedAt, Error, Message
IssueOptionsBindingIP, TTL, MaxUses, BindUID
ModerationItemType, Text, ImageURL (usa los helpers TextItem() / ImageURLItem())
ModerationResultOK, Flagged, Categories, ContentType, Raw, Error, Message; método HasCategory(...names)

Enlaces

MIT-licensed examples · CaptchaLa is operated independently