captcha

package
v1.9.3 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 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