在Next.js表单中添加ReCaptcha的方法

650 阅读1分钟

ReCaptcha是谷歌对垃圾邮件和滥用表单的解决方案。

它是一个宝贵的工具。首先在www.google.com/recaptcha,如果你还没有创建一个账户,并添加你的网站域名。

获取V2版,并选择 "我不是机器人 "复选框。

你会得到一个网站密钥和一个网站秘密。

将秘密存储在你的.env 文件中。

RECAPTCHA_SECRET=<....>

现在在你的Next.js网站上用npm安装react-google-recaptcha

npm install react-google-recaptcha

现在在你有表单的页面中,导入它。

import ReCAPTCHA from 'react-google-recaptcha'

然后你把它添加到JSX中。

<ReCAPTCHA size="normal" sitekey="<YOUR SITE KEY>" />

你应该在表单中看到它。

现在,如果你尝试提交你的表单,它可以工作,因为它没有做任何事情。任何人,包括机器人,都可以成功提交表单,甚至不需要点击 "我不是机器人 "按钮。

你需要在服务器端验证验证码,使其发挥作用。

我想你把表单发送到Next.js的API路由。在那里,添加一个validateCaptcha 方法。

const validateCaptcha = (response_key) => {
  return new Promise((resolve, reject) => {
    const secret_key = process.env.RECAPTCHA_SECRET

    const url = `https://www.google.com/recaptcha/api/siteverify
    secret=${secret_key}&response=${response_key}`

    fetch(url, {
      method: 'post'
    })
      .then((response) => response.json())
      .then((google_response) => {
        if (google_response.success == true) {
          resolve(true)
        } else {
          resolve(false)
        }
      })
      .catch((err) => {
        console.log(err)
        resolve(false)
      })
  })
}

现在在请求处理的主代码中,在做其他事情之前添加这个。

if (!(await validateCaptcha(req.body['g-recaptcha-response']))) {
  return res.redirect(`/captcha`)
}
delete req.body['g-recaptcha-response']

在Next.js中创建一个/captcha 页面,以便在验证码检查无效的情况下重定向。

在前端,你应该在提交表单前添加一些验证。

<form
  method='post'
  action='/api/new'
  enctype='multipart/form-data'
  onSubmit={event => {
    if (grecaptcha.getResponse() === '') {
      event.preventDefault()
      alert("Please click <I'm not a robot> before sending the job")
    }
  }}
>
...