Skip to content

SDK Go Server

SDK oficial server-side em Go — github.com/Captcha-La/captchala-go.

Três tarefas que o SDK executa para você:

  1. Validar — verifica um pass token pt_ vindo do SDK do navegador.
  2. Emitir — cunha um server token sct_ de uso único para vincular o próximo desafio a uma action / IP / UID específica.
  3. Moderar — moderação de conteúdo multimodal (texto + imagem) contra o mesmo pipeline compatível com OpenAI usado pelo painel.

Instalação

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

Apenas stdlib. Sem dependências externas.

Validar (token pt_)

Passe o IP do usuário final (de CF-Connecting-IP / X-Forwarded-For, com fallback para RemoteAddr). É opcional, mas recomendado — é usado para verificações de risco adicionais.

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
}

Não tem o IP à mão? Use client.Validate(token) — ele ainda verifica, apenas sem o sinal de risco extra baseado no IP.

Se o server_token original foi emitido com bind_uid, compare:

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

O contexto do momento da resolução também é retornado em result.CaptchaArgs para sua referência:

go
ip := result.CaptchaArgs.UserIP   // IP do visitante registrado no momento da resolução

Emitir um server token

Recomendado para fluxos de alto valor (login, cadastro, pagamento): o backend cunha um token sct_ de uso único, entrega ao navegador, o navegador o usa como a prop serverToken. De uso único, com escopo de action e opcionalmente vinculado 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

Atalho apenas com padrões:

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

Moderar conteúdo

Multimodal — aceita uma slice de ModerationItem (texto e/ou image_url em formato compatível com 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
    }
}

Atalho para texto puro:

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

As categorias são definidas pelo modelo; itere result.Categories de forma defensiva em vez de fixar um conjunto rígido.

Tipos

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

MIT-licensed examples · CaptchaLa is operated independently