Vercel + Nuxt.js で reCAPTCHA を導入する方法 (リメイク)

2022/03/09 14:49公開

皆さん、こんにちは。

今回は、Vercelを用いてreCAPTCHAを導入してBot対策する方法を解説していきます。Vercelを用いた方法の日本語記事はざっと探しても見当たらなかったので、記事を書いてみます。

以前投稿した記事は一部誤っている部分があったため、再投稿です。

Table of Contents
  1. 下準備
  2. 実装
    1. クライアント側
    2. サーバー側

下準備

まず、reCAPTCHA のコンソール画面から利用登録します。以下のページに飛んでください。

すると、以下の画面が表示されるはずです。

image

ここでは、以下のように選択・入力してください。

ラベル:任意の名前 (サイト名)

reCAPTCHA タイプ:reCAPTCHA v3 を選択

ドメイン:公開予定のドメインを入力

「reCAPTCHA 利用条件に同意する」にチェックを入れる

送信後、「サイトキー」「シークレットキー」 が表示されますが、これは後で使用しますのでページは閉じないでください。

実装

ここからは実装です。reCAPTCHA は、以下のような仕組みで成り立っています。

  1. ユーザーがフォームの「送信」をクリックする
  2. クライアント側で検証し、トークンを生成
  3. トークンをサーバーに送り、検証し、結果を返却
  4. 結果が設定したスコアより高ければフォームの送信処理をする

reCAPTCHAでは、利用者がどれだけ人間だと思われるかのスコアが結果として帰ってきます。しきい値を上げればボットをたくさん弾けますし、低くすれば誤検知のリスクが下がります。

クライアント側

今回はNuxt.jsを用いて実装しますが、それぞれのフレームワークに適宜読み替えてください。

まず、スクリプトをロードします。以下をnuxt.config.jsに追記してください。

export default {
  head() {
    return {
      script: [
        {
          src: "https://www.google.com/recaptcha/api.js?render=<SITE-KEY>"
        }
      ]
    }
  }
}

<SITE-KEY>部分は先程のサイトキーに置き換えてください。

次に、送信ボタンのクリック時の処理を書きます。axiosパッケージをインストールしていない場合は、npm i axios もしくは yarn add axios でインストールしておいてください。

grecaptcha.ready(() => {
  grecaptcha.execute("<SITE-KEY>", {action: 'submit'}).then((token) => {    
    axios.get("/api/checkRecaptcha?response=" + encodeURIComponent(token)).then(async (response) => {
      if (response.data.success) {
                // スコアは任意で変更
        if (response.data.score >= 0.5) {
                    // 送信処理
                }
      }
    })
  })
})

同じく、<SITE-KEY>部分は先程のサイトキーに置き換えてください。

ここで、VercelのサーバーのAPIを叩いて、トークンを検証します。スコアのしきい値の目安は0.5くらいが良いと思います。試してみたところ、ボタンを1回だけ押すと0.9、数回連打すると0.7、何回も連打すると0.3、というように下がっていきました。

サーバー側

次は、Nuxt.jsのプロジェクトルートにapiフォルダーを作成し、その中にcheckRecaptcha.jsを作成します。中身は以下です。

const axios = require("axios").default

module.exports = (req, res) => {
  const response = req.query.response
  console.log("recaptcha response", response)
  axios.post(`https://recaptcha.google.com/recaptcha/api/siteverify?secret=<SECRET-KEY>&response=${response}`).then(result => {
    // console.log("recaptcha result", result)

    if (result.data.success) {
      res.send({success: true})
    } else {
      res.send({
        success: false
      })
    }
  }).catch(reason => {
    console.log("Recaptcha request failure", reason)
    res.send("Recaptcha request failed.")
  })
}

<SECRET-KEY>部分は最初のシークレットキーに置き換えてください。

エミュレーションするには、yarn devではなく、Vercelのコマンドラインツールを利用します。yarn add vercelでインストールし、vercel devコマンドを実行します。初回は色々表示されるかもしれませんが、読めば分かるはずです。

これでVercelにデプロイすれば、reCAPTCHAで認証が可能になります。