Back to Supabase

CAPTCHA support with Cloudflare Turnstile

apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx

1.26.082.2 KB
Original Source

Cloudflare Turnstile is a friendly, free CAPTCHA replacement, and it works seamlessly with Supabase Edge Functions to protect your forms. View on GitHub.

Setup

Code

Create a new function in your project:

bash
supabase functions new cloudflare-turnstile

And add the code to the index.ts file:

ts
import { withSupabase } from 'npm:@supabase/server@^1'

console.log('Hello from Cloudflare Trunstile!')

function ips(req: Request) {
  return req.headers.get('x-forwarded-for')?.split(/\s*,\s*/)
}

// `withSupabase` handles CORS and preflight requests for you.
export default {
  fetch: withSupabase({ auth: 'none' }, async (req) => {
    const { token } = await req.json()
    const clientIps = ips(req) || ['']
    const ip = clientIps[0]

    // Validate the token by calling the
    // "/siteverify" API endpoint.
    let formData = new FormData()
    formData.append('secret', Deno.env.get('CLOUDFLARE_SECRET_KEY') ?? '')
    formData.append('response', token)
    formData.append('remoteip', ip)

    const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'
    const result = await fetch(url, {
      body: formData,
      method: 'POST',
    })

    const outcome = await result.json()
    console.log(outcome)
    if (outcome.success) {
      return Response.json({ success: true })
    }
    return Response.json({ success: false })
  }),
}

Deploy the server-side validation Edge Functions

bash
supabase functions deploy cloudflare-turnstile --no-verify-jwt
supabase secrets set CLOUDFLARE_SECRET_KEY=your_secret_key

Invoke the function from your site

js
const { data, error } = await supabase.functions.invoke('cloudflare-turnstile', {
  body: { token },
})