Vercel で reCAPTCHA を導入する方法 【Nuxt.js】

公開 2021-05-18 15:05 / 最終更新 2021-05-19 06:31
カテゴリー Nuxt.js

皆さん、こんにちは。

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

reCAPTCHA とは

「そんなの知ってるよ」って人は適当に読み飛ばしてください。

reCAPTCHAとは、Google LLCの提供するスパム・ボット対策サービスです。グリッドから信号機選ばされたりするあれと同じサービスです。

実はreCAPTCHAは年々進化していて、最初は写真上の物体を選ばせるタイプのものでしたが、それからチェックボックスにチェックを入れるタイプ、そしてついに何も表示されないものとなっていきました。

チェックボックスにチェックを入れるタイプ、そして何も表示されないタイプでは、カーソルの動作などからボットを判定しているらしいです。今回は、「何も表示されないタイプ」を利用します。

下準備

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

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

image

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

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

reCAPTCHA タイプ:reCAPTCHA v3 を選択

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

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

送信後、「サイトキー」と「シークレットキー」が表示されますが、これは後で使用します。

実装

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

  1. ユーザーがフォームの「送信」をクリックする
  2. クライアント側で検証し、トークンを生成 *
  3. トークンをサーバーに送り、正しいものであるか検証し、結果を返却 *
  4. OKが帰ってきたらフォームの送信処理をする

といった流れです。(「*」付きは、私も詳しい仕組みはよく分かっていません。)それでは、まずはクライアント側で実装をします。

クライアント側

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

まず、スクリプトをロードします。以下をreCAPTCHAを適用するフォームのあるページに追記してください。

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

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

次に、フォームのクリックイベント部で処理を書きます。(HTMLボタンに直接書く方法はこちらをご覧ください。)

grecaptcha.ready(() => {
  grecaptcha.execute("<SITE-KEY>", {action: 'submit'}).then((token) => {    
    axios.get("/api/checkRecaptcha?response=" + encodeURIComponent(token)).then(async (response) => {
      if (response.data.success) {
        // フォーム送信処理
      }
    })
  })
})

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

ここで、VercelのサーバーのAPIを叩いて、トークンを検証します。

サーバー側

次は、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>部分は最初のシークレットキーに置き換えてください。

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

コメント
コメントする

※ニックネームの変更はCookieを削除することで行えます。(ただし、過去に書き込んだコメントの編集・削除はできなくなります。)

コメント本文

※reCAPTCHAによるボット判定を行っているため、送信に少々時間がかかる場合があります。ご了承ください。

送信しました。

確認

コメントを削除しますか?

返信

返信を入力

arrow_upward