Help us shape the future of Go! Take the 2026 Go Developer Survey

captcha

package
v1.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package captcha provides a small pluggable captcha verifier interface and a Cloudflare Turnstile implementation.

Implementations are stateless and safe for concurrent use. Failures are classified into typed sentinels so callers can implement fail-open vs fail-closed policy without parsing provider responses.

Index

Constants

View Source
const DefaultTurnstileTimeout = 5 * time.Second

DefaultTurnstileTimeout is the default HTTP timeout for the Turnstile verifier. Captcha verification sits on the auth path; we'd rather fail fast than hang the request.

Variables

View Source
var (
	ErrMissingToken     = errors.New("captcha: missing token")
	ErrInvalidToken     = errors.New("captcha: invalid token")
	ErrDuplicateToken   = errors.New("captcha: token already used")
	ErrTransientFailure = errors.New("captcha: transient verifier failure")
)

Common sentinel errors that map to recurring failure modes.

Functions

This section is empty.

Types

type Result

type Result struct {
	Success     bool
	ChallengeTS string   // RFC3339 timestamp of the challenge solve
	Hostname    string   // hostname of the challenge issuer
	Action      string   // optional client-supplied action binding (echoed by provider)
	ErrorCodes  []string // provider-specific error codes (unused on success)
}

Result is the structured response from a verifier returned on success.

For the Turnstile verifier, ChallengeTS, Hostname, and Action are populated from the provider response and are suitable for audit-log enrichment. ErrorCodes is unused on success (failures return (nil, err) instead).

type TurnstileVerifier

type TurnstileVerifier struct {
	// contains filtered or unexported fields
}

TurnstileVerifier verifies Cloudflare Turnstile tokens.

It is stateless and safe for concurrent use. Construct via NewTurnstileVerifier; the zero value is not usable.

func NewTurnstileVerifier

func NewTurnstileVerifier(secret string, httpClient *http.Client) *TurnstileVerifier

NewTurnstileVerifier returns a verifier configured with the given secret. httpClient may be nil: it defaults to a client with a 5s timeout, whose calls to Cloudflare are client spans under the request's span.

func (*TurnstileVerifier) Verify

func (v *TurnstileVerifier) Verify(ctx context.Context, token, remoteIP, action string) (*Result, error)

Verify implements Verifier.

On success: returns (*Result, nil) with ChallengeTS, Hostname, and Action populated from the provider response. If the caller supplied a non-empty action and it does not match the response's action, returns (nil, *VerifyError{Codes: ["action-mismatch"]}).

On failure: returns (nil, err) — ErrMissingToken if token is empty; ErrTransientFailure on network/parse/non-2xx; otherwise the classified sentinel for known Turnstile error codes or a *VerifyError preserving the provider codes.

Note: Cloudflare's siteverify does NOT accept "action" as a request form field; the action is bound at widget render time and echoed back in the response. We therefore do not send it on the wire — we only compare the echoed value against what the caller expects.

type Verifier

type Verifier interface {
	// Verify returns a populated *Result and nil error on success. On failure
	// it returns (nil, err) — typically a sentinel (ErrMissingToken,
	// ErrInvalidToken, ErrDuplicateToken, ErrTransientFailure) or a wrapped
	// *VerifyError carrying provider-specific codes.
	//
	// The remoteIP is the client's IP (can be empty if unknown). The action
	// is an optional binding the caller expects: when non-empty, the verifier
	// compares it against the action echoed back by the provider and returns
	// *VerifyError{Codes: ["action-mismatch"]} if they differ.
	Verify(ctx context.Context, token, remoteIP, action string) (*Result, error)
}

Verifier validates a captcha challenge token. Implementations are stateless and safe for concurrent use.

type VerifyError

type VerifyError struct {
	Codes []string
}

VerifyError is returned when a verifier rejects a token. Codes are the provider-specific reasons. Use errors.As to extract.

func (*VerifyError) Error

func (e *VerifyError) Error() string

Error implements error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL