Documentation Index
Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Thecaptcha middleware verifies CAPTCHA tokens to protect forms and APIs from bots. It supports multiple providers including Google reCAPTCHA (v2/v3), hCaptcha, and Cloudflare Turnstile.
Use it when you need:
- Bot protection for forms
- Spam prevention
- Account creation protection
- API abuse prevention
Installation
Quick Start
Configuration
Options
| Option | Type | Default | Description |
|---|---|---|---|
Provider | Provider | ProviderRecaptchaV2 | CAPTCHA provider |
Secret | string | - | Secret key from provider |
TokenLookup | string | "form:g-recaptcha-response" | Where to find token |
MinScore | float64 | 0.5 | Minimum score for v3 providers |
Verifier | func(token string, c *mizu.Ctx) (bool, error) | - | Custom verifier |
ErrorHandler | func(*mizu.Ctx, error) error | - | Custom error handler |
SkipPaths | []string | - | Paths to skip verification |
Timeout | time.Duration | 10s | Verification timeout |
Providers
Examples
Google reCAPTCHA v2
Google reCAPTCHA v3
hCaptcha
Cloudflare Turnstile
Skip Certain Paths
Custom Token Location
Custom Error Handler
Custom Verifier
Route-Specific Protection
API Reference
Functions
Error Types
Provider Comparison
| Provider | Type | Privacy | Free Tier |
|---|---|---|---|
| reCAPTCHA v2 | Checkbox | Yes | |
| reCAPTCHA v3 | Invisible | Yes | |
| hCaptcha | Checkbox | Privacy-focused | Yes |
| Turnstile | Invisible | Cloudflare | Yes |
Best Practices
- Use v3/invisible CAPTCHAs for better UX
- Set appropriate score thresholds for v3
- Monitor verification failures for tuning
- Have fallback for CAPTCHA failures
- Test with automation tools
Technical Details
Token Extraction
The middleware supports extracting tokens from three locations:- Form:
form:field-name- Extracts from POST form data - Header:
header:Header-Name- Extracts from HTTP headers - Query:
query:param-name- Extracts from URL query parameters
TokenLookup option uses the format source:key where source is one of form, header, or query.
Verification Flow
- Request Filtering: Skips verification for safe methods (GET, HEAD, OPTIONS) and configured skip paths
- Token Extraction: Retrieves token based on
TokenLookupconfiguration - Verification:
- For custom verifiers: Calls the provided
Verifierfunction - For provider verifiers: Makes HTTP POST to providerβs API with secret, token, and client IP
- For custom verifiers: Calls the provided
- Score Validation: For v3 providers (reCAPTCHA v3, Turnstile), validates score against
MinScorethreshold - Error Handling: Uses custom
ErrorHandlerif provided, otherwise returns default 400 response
Client IP Detection
The middleware detects client IP in the following order:X-Forwarded-Forheader (first IP in comma-separated list)X-Real-IPheaderRemoteAddrfrom request (strips port if present)
Provider API Integration
Each provider has a specific verification endpoint:- reCAPTCHA v2/v3:
https://www.google.com/recaptcha/api/siteverify - hCaptcha:
https://hcaptcha.com/siteverify - Turnstile:
https://challenges.cloudflare.com/turnstile/v0/siteverify
secret: Your secret keyresponse: The CAPTCHA tokenremoteip: Client IP address (optional)
Default Values
| Setting | Default Value |
|---|---|
| Provider | ProviderRecaptchaV2 |
| TokenLookup | "form:g-recaptcha-response" |
| MinScore | 0.5 |
| Timeout | 10s |
Error Types
The middleware defines three specific error types:ErrMissingToken: Token not found in the specified lookup locationErrInvalidToken: Token verification failed (invalid or low score)ErrVerifyFailed: HTTP request to provider API failed
Testing
Test Coverage
| Test Case | Description | Expected Behavior |
|---|---|---|
TestWithOptions_MissingToken | POST request without CAPTCHA token | Returns 400 Bad Request |
TestWithOptions_CustomVerifier (valid) | Custom verifier with valid token | Request proceeds (200 OK) |
TestWithOptions_CustomVerifier (invalid) | Custom verifier with invalid token | Returns 400 Bad Request |
TestWithOptions_SkipSafeMethods | GET request without token | Request proceeds (200 OK), CAPTCHA skipped |
TestWithOptions_SkipPaths | POST to path in SkipPaths | Request proceeds (200 OK), CAPTCHA skipped |
TestWithOptions_HeaderToken | Token provided via HTTP header | Token extracted from header, verification succeeds |
TestWithOptions_QueryToken | Token provided via query parameter | Token extracted from query, verification succeeds |
TestWithOptions_CustomErrorHandler | Invalid token with custom error handler | Custom handler returns 403 Forbidden with JSON |
TestCustom | Custom verifier function | Custom verification logic applied successfully |
TestNew | Creating middleware with New() | Middleware instance created with defaults |
TestErrors | Error message validation | All error types return correct messages |
TestExtractToken_InvalidLookup | TokenLookup without colon separator | Returns 400 Bad Request (token not found) |
TestVerifyToken_WithMockServer (valid) | Valid token verified by mock server | Returns 200 OK |
TestVerifyToken_WithMockServer (invalid) | Invalid token verified by mock server | Returns 400 Bad Request |
TestVerifyToken_RecaptchaV3Score (high) | reCAPTCHA v3 with score above threshold | Returns 200 OK |
TestVerifyToken_RecaptchaV3Score (low) | reCAPTCHA v3 with score below threshold | Returns 400 Bad Request |
TestVerifyToken_ServerError | Provider API returns 500 error | Returns 400 Bad Request |
TestVerifyToken_InvalidJSON | Provider returns malformed JSON | Returns 400 Bad Request |
TestVerifyToken_UnknownProvider | Unknown provider type | Returns 400 Bad Request |
TestGetClientIP_XForwardedFor | X-Forwarded-For header present | Extracts first IP from header, sends to provider |
TestGetClientIP_XRealIP | X-Real-IP header present | Extracts IP from header, sends to provider |
TestReCaptchaV2 | ReCaptchaV2 constructor | Creates middleware with reCAPTCHA v2 config |
TestReCaptchaV3 | ReCaptchaV3 constructor | Creates middleware with reCAPTCHA v3 config |
TestHCaptcha | HCaptcha constructor | Creates middleware with hCaptcha config |
TestTurnstile | Turnstile constructor | Creates middleware with Turnstile config |
TestWithOptions_VerifierError | Custom verifier returns error | Returns 400 Bad Request |
TestWithOptions_HeadMethod | HEAD request without token | Request proceeds (200 OK), CAPTCHA skipped |
TestWithOptions_OptionsMethod | OPTIONS request without token | Request proceeds (200 OK), CAPTCHA skipped |
Security Considerations
- Secret Key - Never expose secret key in frontend code
- Score Tuning - Adjust v3 scores based on traffic patterns
- Timeout - Set reasonable timeout for verification
- Fallback - Have manual review process for edge cases