Home > Web Front-end > JS Tutorial > body text

Migrating from Google&#s reCAPTCHA to Cloudflare Turnstile?

王林
Release: 2024-07-23 12:19:58
Original
213 people have browsed it

Migrating from Google

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.

What's a CAPTCHA?

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:

  1. hCaptcha. We considered it at first, but their pricing is quite similar to new Google's pricing.
  2. Cloudflare Turnstile. We are huge fans of Cloudflare, and definitely looked into it. As for now, it's a free service.

Let's dig in.

Moving away from Google reCAPTCHA...

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' })
    }

    ...
Copy after login

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.

... to Cloudflare Turnstile

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 }
Copy after login

Once the middleware is in place, we can apply it to any requests:

// index.js
app.post('/api/ai-email-writer', aiRateLimiter, turnstile, aiEmailWriter)
Copy after login

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' })
    }

    ...
Copy after login

Conclusion

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 Google&#s reCAPTCHA to Cloudflare Turnstile?. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!