captcha

package
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: MIT Imports: 10 Imported by: 0

README

CAPTCHA

简体中文

captcha verifies tokens with Cap Standalone, Cloudflare Turnstile and Google reCAPTCHA v2/v3. captcha/http provides optional HTTP middleware. Applications supply constructor arguments; neither package reads configuration files or environment variables, manages credentials, nor persists tokens.

Clients

import "github.com/Ithildur/EiluneKit/captcha"

capClient, err := captcha.NewCap(
    "https://cap.example.com/site-key/siteverify",
    secret,
    captcha.Options{},
)

Cap must already be deployed. Use the site key's secret, not the dashboard admin key. The endpoint is the full verification URL; HTTP is supported for private service connections, and HTTPS should be used across untrusted networks.

turnstile, err := captcha.NewTurnstile(secret, captcha.TurnstileOptions{
    Hostname: "example.com",
    Action:   "login",
})

recaptchaV2, err := captcha.NewRecaptchaV2(secret, captcha.RecaptchaV2Options{
    Hostname: "example.com",
})

recaptchaV3, err := captcha.NewRecaptchaV3(secret, captcha.RecaptchaV3Options{
    Hostname: "example.com",
    Action:   "login",
    MinScore: new(0.5),
})

Check each constructor error before using its client. Hostname and action are exact matches when supplied. reCAPTCHA v3 requires a non-empty action; its minimum score defaults to 0.5. An explicit threshold can range from 0 to 1, and the response must contain a valid score even with a zero threshold. These clients use siteverify, not the Google Enterprise Assessment API.

Use a separate client for each action or policy. Constructors validate local arguments without contacting providers. A constructor succeeding does not establish that its secret is accepted by the provider.

Options.HTTPClient optionally supplies an HTTP client; Options.Timeout defaults to five seconds and bounds the whole verification. The client is copied, its transport remains shared, and redirects are disabled. The application owns the transport's lifecycle. Clients support concurrent calls and do not cache verification results or automatically retry requests.

Built-in login

Both auth/http.Options and auth/rbac/http.Options accept Captcha captchahttp.Options. The zero value disables verification. Set Enabled: true and supply Verify: client.Verify to protect POST {BasePath}/login.

import (
    authhttp "github.com/Ithildur/EiluneKit/auth/http"
    "github.com/Ithildur/EiluneKit/captcha"
    captchahttp "github.com/Ithildur/EiluneKit/captcha/http"
)

func newAuthHandler(manager authhttp.TokenManager, login authhttp.LoginAuthenticator,
    enabled bool, secret string,
) (*authhttp.Handler, error) {
    protection := captchahttp.Options{Enabled: enabled}
    if enabled {
        client, err := captcha.NewTurnstile(secret, captcha.TurnstileOptions{
            Hostname: "example.com",
            Action:   "login",
        })
        if err != nil {
            return nil, err
        }
        protection.Verify = client.Verify
    }
    return authhttp.NewHandler(manager, authhttp.Options{
        LoginAuthenticator: login,
        Captcha:            protection,
    })
}

Disabled protection never calls Verify. Enabled protection requires a non-nil verification function; otherwise NewHandler returns an error. Runtime failures never disable protection. Custom verification functions must be concurrency-safe, return nil only on success, and use the captcha error sentinels when applicable.

The login chain installs rate limiting, the existing body limit and Content-Type checks before CAPTCHA. The body limit takes effect when the handler reads the body. CAPTCHA runs before credential authentication; its failures do not create sessions, issue tokens, set login cookies or count as password failures. Refresh, logout and session management remain independent of CAPTCHA.

Enabled login routes declare the required X-Captcha-Token header and the 403 response in generated OpenAPI. Disabled routes retain their existing contract. CAPTCHA remains an additional check on a public login route, not a substitute for authentication or rate limiting.

Custom endpoints

guard, err := captchahttp.New(captchahttp.Options{
    Enabled: true,
    Verify:  client.Verify,
})
if err != nil {
    return err
}
blueprint.Post("/signup", "Sign up", signup, routes.Use(guard))

The middleware also wraps an ordinary http.Handler. captchahttp.New returns nil when disabled; only attach a non-nil middleware. It reads X-Captcha-Token and does not consume or rewrite the body. Applications own custom endpoint metadata, including the required header and error responses.

For tokens in JSON or form bodies, decode the request once in the handler and call client.Verify(r.Context(), token) before business side effects. A nil return means the token passed all configured checks. Do not verify the same token again in another layer.

Browser integration

Use the chosen provider's widget and public site key in the browser. Keep its secret on the server. Submit the returned token with the business request:

await fetch("/auth/login", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Captcha-Token": token,
  },
  body: JSON.stringify({
    username,
    password,
    persistence: "session",
  }),
});

For Cap, obtain the token from the widget's solve event (event.detail.token). For Turnstile or reCAPTCHA v2, use the widget callback token; for reCAPTCHA v3, use the result of grecaptcha.execute with the action expected by the server. Obtain a fresh token for each submission attempt, including after a failed login. Cross-origin applications must allow X-Captcha-Token in their CORS policy.

Errors

Client error (errors.Is) HTTP status Response code
captcha.ErrRequired 400 captcha_required
captcha.ErrRejected 403 captcha_rejected
captcha.ErrMisconfigured 500 captcha_misconfigured
captcha.ErrUnavailable or an unknown custom error 503 captcha_unavailable

Invalid/expired/spent tokens and failed policies are rejected. Explicit provider credential errors are misconfiguration; network failures and unrecognized or malformed responses are unavailable. The client preserves request-context cancellation for errors.Is. Error text omits secrets, tokens, raw provider responses and transport error text. HTTP responses use the existing response.ErrorResponse; applications can wrap Verify to record client errors with their own logger.

Protocol references: Cap, Turnstile, reCAPTCHA verification, reCAPTCHA v3.

Documentation

Overview

Package captcha verifies CAPTCHA tokens with external services. Package captcha 通过外部服务验证 CAPTCHA token。

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrRequired means no token was supplied.
	// ErrRequired 表示未提供 token。
	ErrRequired = errors.New("captcha: token required")
	// ErrRejected means the token or its verification policy was rejected.
	// ErrRejected 表示 token 或其验证策略未通过。
	ErrRejected = errors.New("captcha: verification rejected")
	// ErrMisconfigured means local parameters or provider credentials are invalid.
	// ErrMisconfigured 表示本地参数或服务商凭据无效。
	ErrMisconfigured = errors.New("captcha: misconfigured")
	// ErrUnavailable means verification could not be completed.
	// ErrUnavailable 表示无法完成验证。
	ErrUnavailable = errors.New("captcha: verification unavailable")
)

Functions

This section is empty.

Types

type Client

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

Client verifies tokens concurrently without caching or automatic retries. A nil or zero Client returns ErrMisconfigured from Verify. Client 支持并发验证,不缓存结果或自动重试。 Nil 或零值 Client 的 Verify 返回 ErrMisconfigured。

func NewCap

func NewCap(endpoint, secret string, opts Options) (*Client, error)

NewCap uses the full siteverify URL, including the site key, and its secret. NewCap 使用包含 site key 的完整 siteverify URL 及其 secret。

func NewRecaptchaV2

func NewRecaptchaV2(secret string, opts RecaptchaV2Options) (*Client, error)

NewRecaptchaV2 constructs a Google reCAPTCHA v2 siteverify client. NewRecaptchaV2 构造 Google reCAPTCHA v2 siteverify 客户端。

func NewRecaptchaV3

func NewRecaptchaV3(secret string, opts RecaptchaV3Options) (*Client, error)

NewRecaptchaV3 constructs a Google reCAPTCHA v3 siteverify client. Action must be non-empty; hostname and action checks use exact matching. NewRecaptchaV3 构造 Google reCAPTCHA v3 siteverify 客户端。 Action 不能为空;hostname 和 action 使用精确匹配。

func NewTurnstile

func NewTurnstile(secret string, opts TurnstileOptions) (*Client, error)

NewTurnstile constructs a Cloudflare Turnstile verifier. NewTurnstile 构造 Cloudflare Turnstile 验证客户端。

func (*Client) Verify

func (c *Client) Verify(ctx context.Context, token string) error

Verify consumes token and returns nil only when all verification checks pass. Errors match the package sentinels with errors.Is; cancellation also matches context.Canceled or context.DeadlineExceeded. Error text excludes credentials, tokens, raw provider responses and transport error text. Verify 消费 token,仅在全部验证通过时返回 nil。 错误可通过 errors.Is 匹配包内哨兵;取消还可匹配 context.Canceled 或 context.DeadlineExceeded。错误文本不包含凭据、token、上游原始响应或传输错误文本。

type Options

type Options struct {
	// HTTPClient is copied; its transport remains shared and owned by the caller.
	// Nil uses http.DefaultClient. Redirects are never followed.
	// HTTPClient 会被复制;transport 仍由调用方持有并共享。
	// Nil 使用 http.DefaultClient。不会跟随重定向。
	HTTPClient *http.Client
	// Timeout bounds the entire verification. Zero defaults to five seconds.
	// Timeout 限制整个验证耗时。零值默认为五秒。
	Timeout time.Duration
}

Options controls verification requests. Constructors perform no network I/O. Options 控制验证请求。构造函数不进行网络访问。

type RecaptchaV2Options

type RecaptchaV2Options struct {
	Options
	Hostname string
}

RecaptchaV2Options adds an exact hostname check when non-empty. RecaptchaV2Options 在 hostname 非空时执行精确匹配。

type RecaptchaV3Options

type RecaptchaV3Options struct {
	Options
	Hostname string
	Action   string
	// MinScore is in [0, 1]. Nil defaults to 0.5; the value is copied.
	// MinScore 取值为 [0, 1]。Nil 默认为 0.5;值会被复制。
	MinScore *float64
}

RecaptchaV3Options requires an action and checks the returned score. RecaptchaV3Options 要求提供 action 并检查返回的评分。

type TurnstileOptions

type TurnstileOptions struct {
	Options
	Hostname string
	Action   string
}

TurnstileOptions adds exact hostname and action checks when non-empty. TurnstileOptions 在 hostname 和 action 非空时执行精确匹配。

Directories

Path Synopsis
Package captchahttp protects HTTP endpoints with CAPTCHA verification.
Package captchahttp protects HTTP endpoints with CAPTCHA verification.

Jump to

Keyboard shortcuts

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