Google reCAPTCHA new pricing will be rolled out on August 1st, meaning that you have a few days left to migrate to a cheaper alternative or ensure your bank account is well-funded.
Starting at $1 for 1,000 verifications, it is going to cost a lot. At Mailmeteor, we use reCAPTCHA extensively to protect our services from bots. With Google's pricing change, we calculated that we're about to pay thousands of dollar per month to keep using their reCAPTCHA service.
CAPTCHAs are an essential part of the web. It aims to separate good citizens from bad actors. Essentially, it's a service that will operate on the frontend and generate a token that is transmitted to the backend. The backend then verifies that the token is legit, and, if so, performs the action.
Google did a great job at promoting their own service, but thankfully, there are some alternatives:
Let's dig in.
One of our free tools is an AI Email Writer. It's basically an HTML page that send request to our backend, which then makes to a third-party AI solution.
To protect it from abuse, Google reCAPTCHA was enabled from day one. Here's how the verification was done so far (backend-side):
// index.js app.post('/api/email-ai-writer', recaptcha.middleware.verify, aiEmailWriter) // ai_email_writer.js async function aiEmailWriter(request, response) { try { // Recaptcha if (!request.recaptcha || request.recaptcha.error || !request.recaptcha.data) { console.warn('Recaptcha: verification failed.') return response.status(403).send({ error: true, message: 'Recaptcha: verification failed' }) } else if (request.recaptcha.data.action !== 'aiemailwriter') { console.warn('Recaptcha: bad action name') return response.status(403).send({ error: true, message: 'Recaptcha: bad action name' }) } else if (request.recaptcha.data.score < 0.3) { const score = request.recaptcha.data.score console.warn(`Recaptcha: score is below 0.3 (${score})`) return response.status(403).send({ error: true, message: 'Recaptcha: score too low' }) } ...
That's quite simple and it's an essential part of why Google reCAPTCHA was so popular. The footprint is very limited and it's really easy to implement. For the most curious ones, we leveraged the express-recaptcha package to make it really easy to implement.
When migrating to Turnstile, we couldn't found an NPM package, so we had to write a middleware to process the token. Here's how it looks like:
// middlewares/turnstile.js const turnstile = async (request, response, next) => { try { // Turnstile injects a token in "cf-turnstile-response". const token = request.query['cf-turnstile-response'] const ip = request.header('CF-Connecting-IP') if (!token) { throw new Error('Missing CloudFlare Turnstile Token') } // Validate the token by calling the // "/siteverify" API endpoint. const formData = new FormData() formData.append('secret', process.env.CLOUDFLARE_TURNSTILE_SECRET_KEY) formData.append('response', token) if (ip) formData.append('remoteip', ip) const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify' const result = await fetch(url, { body: formData, method: 'POST', }) // Process the verification outcome const outcome = await result.json() if (!outcome.success) { throw new Error('CloudFlare Turnstile declined the token') } request.turnstile = outcome // If authentified, go to next middleware next() } catch (err) { console.error(err) return response.status(403).send('Forbidden') } } export { turnstile }
Once the middleware is in place, we can apply it to any requests:
// index.js app.post('/api/ai-email-writer', aiRateLimiter, turnstile, aiEmailWriter)
And inside the function that treats the request, it's quite similar to what we had previously:
// ai_email_writer.js async function aiEmailWriter(request, response) { try { // CloudFlare Turnstile protection if (!request.turnstile || request.turnstile.error) { console.warn('Recaptcha: verification failed.') return response.status(403).json({ error: true, message: 'Recaptcha: verification failed' }) } else if (request.turnstile.action !== 'aiemailwriter') { console.warn('Recaptcha: bad action name') return response.status(403).json({ error: true, message: 'Recaptcha: bad action name' }) } ...
Migrating from reCAPTCHA to Turnstile is straightforward and shouldn't take more than a few hours. It works quite similar and will definitely save you a lot of money at the same time.
I didn't cover the frontend in this article, because we use an invisible widget that our users don't see. But Turnstile's documentation covers extensively how to use their interactive widgets.
Call it a day!
The above is the detailed content of Migrating from Googles reCAPTCHA to Cloudflare Turnstile?. For more information, please follow other related articles on the PHP Chinese website!