Open1

Google ReCaptcha

かるでねかるでね

Next.jsに組み込む手順

Google ReCaptchaの登録

以下でドメインなどを登録して、「サイトキー」と「シークレットキー」を生成。
https://www.google.com/recaptcha/about/

フロントエンド

npm install --save react-google-recaptcha-v3

できる限り上位で読み込む方が良いので、layout.tsxなどで読み込む。

"use client";

import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
import { NEXT_PUBLIC_RECAPTCHA_CLIENT_KEY } from "@config/config";
import { ReactNode } from "react";

export default function ReCaptcha({ children }: { children: React.ReactNode }) {
  return (
    <GoogleReCaptchaProvider
      reCaptchaKey={NEXT_PUBLIC_RECAPTCHA_CLIENT_KEY}
      language="ja"
    >
      {children}
    </GoogleReCaptchaProvider>
  );
}

リキャプチャを導入したいページで以下を導入する。

import {
  useGoogleReCaptcha,
} from "react-google-recaptcha-v3";

...

const { executeRecaptcha } = useGoogleReCaptcha();

const reCaptchaVerify = async (): Promise<boolean> => {
    if (!executeRecaptcha) {
      return false;
    }
    // executeRecaptcha内の文字列は任意
    const recaptchaToken = await executeRecaptcha("wallet");
    
    // reCaptchaの検証を行うバックエンドAPIリクエスト
    const responseReCaptchaVerify = await recaptureVerify(address, recaptchaToken);

    console.log(`responseReCaptchaVerify: ${JSON.stringify(responseReCaptchaVerify)}`);

    return responseReCaptchaVerify.success
  };

バックエンド

バックエンドからGoogle側へリクエストを投げて検証します。
以下でフロントからのリクエストを受け付けています。

app.post("/v1/recaptcha", async (_req: Request, res: Response) => {
  try {
    const reCaptchaSecretKey = `secret=${RECAPTCHA_SECRET_KEY}&response=${_req.body.token}`;
    const responseReCaptchaData = await axios
      .post(
        "https://www.google.com/recaptcha/api/siteverify",
        reCaptchaSecretKey,
        {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        }
      )
    if (responseReCaptchaData.data.success) {
      res.status(200).send(responseReCaptchaData?.data);
      return;
    }
    );
    res.status(500).send({ message: "Internal server error" });
  } catch (err) {
    res.status(500).send({ message: "Internal server error" });
  }
});

レスポンス

検証結果のレスポンスは以下になります。

{
  success: true,
  challenge_ts: '2022-08-15T01:57:53Z',
  hostname: 'localhost',
  score: 0.9,
  action: 'Contaåct'
}

参考

https://www.npmjs.com/package/react-google-recaptcha-v3

https://zenn.dev/angelecho/articles/daeb265bb3bf4b

https://cumak.net/blog/recaptcha-approuter/

https://karukichi-blog.netlify.app/blogs/nextjs-recaptcha

https://blog.fundely.co.jp/tech/2023/06/14/react-google-recaptcha-v3の特徴と導入方法/