Skip to content

Example 5: Captcha Challenge (Turnstile / hCaptcha / reCAPTCHA) ​

Instead of dropping connections or returning static error codes, RouteWarden can serve interactive Captcha challenges on sensitive paths using Cloudflare Turnstile, hCaptcha, or Google reCAPTCHA.


Is a captcha.html File Required? ​

TIP

No external captcha.html file is required!
RouteWarden has a built-in, mobile-responsive dark-mode HTML template embedded directly into the Go binary. When mode: captcha is enabled, RouteWarden automatically:

  1. Injects the official provider JavaScript SDK.
  2. Renders the appropriate widget container.
  3. Populates your custom title and site key.

(Optional: Pass an HTML template string into response.captcha.template to override the design.)


Supported Providers ​

Providerresponse.captcha.providerInjected SDK ScriptWidget Class
hCaptchahcaptchahttps://js.hcaptcha.com/1/api.js<div class="h-captcha">
Cloudflare Turnstileturnstilehttps://challenges.cloudflare.com/turnstile/v0/api.js<div class="cf-turnstile">
Google reCAPTCHA v2recaptchahttps://www.google.com/recaptcha/api.js<div class="g-recaptcha">

1. hCaptcha Configuration Example ​

This example protects /admin and /login with hCaptcha (using the official hCaptcha test site key 10000000-ffff-ffff-ffff-000000000001):

# dynamic_conf.ymlhttp:  middlewares:    hcaptcha-barrier:      plugin:        routewarden:          enabled: true          pathPatterns:            - '(?i)^/(admin|login)(/.*)?$'          response:            mode: captcha            statusCode: 403            captcha:              provider: "hcaptcha"              siteKey: "10000000-ffff-ffff-ffff-000000000001"              title: "Human Verification (hCaptcha)"  routers:    app-router:      rule: "Host(`app.example.com`)"      entryPoints:        - web      middlewares:        - hcaptcha-barrier      service: app-service

2. Cloudflare Turnstile Configuration Example ​

# dynamic_conf.ymlhttp:  middlewares:    turnstile-barrier:      plugin:        routewarden:          enabled: true          pathPatterns:            - '(?i)^/login(/.*)?$'            - '(?i)^/reset-password(/.*)?$'          response:            mode: captcha            statusCode: 403            captcha:              provider: "turnstile"              siteKey: "1x00000000000000000000AA"              title: "Security Verification Required"  routers:    login-router:      rule: "Host(`login.example.com`)"      entryPoints:        - web      middlewares:        - turnstile-barrier      service: login-service

3. Docker Compose Example ​

services:  traefik:    image: traefik:v3.1    command:      - "--providers.docker=true"      - "--entrypoints.web.address=:80"      - "--experimental.plugins.routewarden.modulename=github.com/routewarden/traefik-warden"      - "--experimental.plugins.routewarden.version=v1.2.1"    ports:      - "80:80"    volumes:      - "/var/run/docker.sock:/var/run/docker.sock:ro"  app:    image: nginx:alpine    labels:      - "traefik.enable=true"      - "traefik.http.routers.app.rule=Host(`app.localhost`)"      - "traefik.http.routers.app.middlewares=hcaptcha-barrier"      - "traefik.http.middlewares.hcaptcha-barrier.plugin.routewarden.enabled=true"      - "traefik.http.middlewares.hcaptcha-barrier.plugin.routewarden.pathPatterns=(?i)^/(admin|login)(/.*)?$"      - "traefik.http.middlewares.hcaptcha-barrier.plugin.routewarden.response.mode=captcha"      - "traefik.http.middlewares.hcaptcha-barrier.plugin.routewarden.response.captcha.provider=hcaptcha"      - "traefik.http.middlewares.hcaptcha-barrier.plugin.routewarden.response.captcha.siteKey=10000000-ffff-ffff-ffff-000000000001"

Released under the MIT License.