CAPTCHA support with Cloudflare Turnstile
Cloudflare Turnstile is a friendly, free CAPTCHA replacement, and it works seamlessly with Supabase Edge Functions to protect your forms. View on GitHub.
Setup#
- Follow these steps to set up a new site: https://developers.cloudflare.com/turnstile/get-started/
- Add the Cloudflare Turnstile widget to your site: https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/
Code#
Create a new function in your project:
supabase functions new cloudflare-turnstileAnd add the code to the index.ts file:
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#
supabase functions deploy cloudflare-turnstile --no-verify-jwtsupabase secrets set CLOUDFLARE_SECRET_KEY=your_secret_keyInvoke the function from your site#
const { data, error } = await supabase.functions.invoke('cloudflare-turnstile', { body: { token },})