作成日時:2023年8月19日 23:24
更新日時:2023年8月19日 23:47
Next.js
Tutorial
HTNCodeです。
今回、Next.js 13.4でreCAPTCHA v3を導入しましたのでメモ。
※かなり粗削りな実装をした気がするので、間違い等あれば、ぜひお問い合わせフォームよりご指摘いただけますと幸いです!
■HTNCode Official Site_お問い合わせフォーム
https://www.htncode.com/contact
reCAPTCHAとは、お問い合わせフォーム等を利用してbot による迷惑メールやスパム攻撃が行われることを防いでくれるGoogle提供サービスです。
自分たちに迷惑メール等が送られてくるならまだましなのですが、お問い合わせフォームって自動で受付完了メールとか送られますよね。
それを利用して、全然関係のない方にも大量に攻撃されちゃうわけです。これを防ぐことは、もはや必須のマナーですね。
■Google_reCAPTCHA
https://www.google.com/recaptcha/about/
reCAPTCHAを利用するにはまず登録が必要なので、
その辺は「あさくらーめん@フルスタックエンジニア」さんのブログをご参考ください。
今回私も参考にさせていただきました。ありがとうございます。
■Zenn_Next.jsのWEBサイトにreCAPTCHA(v3)を導入する(あさくらーめん@フルスタックエンジニア)
https://zenn.dev/angelecho/articles/daeb265bb3bf4b
appディレクトリ配下は以下構成になっています(関係ないファイル等は省略)。
app
├api
│ └recaptcha
│ └route.ts
├contact
│ └page.tsx
│
└layout.tsx
npm install --save react-google-recaptcha-v3
RECAPTCHA_SERVER_SECRET_KEY="シークレットキーを入力"
<GoogleReCaptchaProvider>を使って、コンポーネントをラップします。
layout.tsxでラップすることで、サイト全体でreCAPTCHAが働いてくれるようになります。
※関係のない記述部分は省略
"use client";
import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<GoogleReCaptchaProvider
reCaptchaKey="ここにサイトキーを入力(envファイルでもOK")"
language="ja"
>
<Component />
</GoogleReCaptchaProvider>
);
}
app/api/recaptchaフォルダ内にroute.tsファイルを作成し、以下のように記述します。
import { NextResponse } from "next/server";
type Token = {
token: string;
};
export async function POST(req: Request) {
const data: Token = await req.json();
const { token } = data;
const serverSecretKey = `secret=${process.env.RECAPTCHA_SERVER_SECRET_KEY}&response=${token}`;
const responce_recaptcha = await fetch(
"https://www.google.com/recaptcha/api/siteverify",
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: serverSecretKey,
}
);
const responceJson_recaptcha = await responce_recaptcha.json();
if (responceJson_recaptcha.success) {
return NextResponse.json({ message: "success" });
} else {
return NextResponse.json({
message: "error",
error: "reCAPTCHA verificationに失敗しました。",
});
}
}
最後にお問い合わせフォームのcontact/page.tsxファイル内で、送信ボタンをクリックした際に実行される処理部分に追記をします。
reCAPTCHAがbotかどうかを判定し、レスポンスを返してくるので、その結果に応じて処理を分岐させます。
"use client";
import { NextPage } from "next";
import { useGoogleReCaptcha } from "react-google-recaptcha-v3";
const Contact: NextPage = () => {
//reCAPTCHAの処理の関数定義
const { executeRecaptcha } = useGoogleReCaptcha();
return () => {
//メール送信処理
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
// reCAPTCHAからtokenを取得
let token = "";
if (executeRecaptcha) {
token = await executeRecaptcha("contact");
} else {
alert("何らかのエラーが発生しました。再度お試しください。");
}
// サーバーへrecaptcha認証要求
const responce_server = await fetch("/api/recaptcha", {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
token,
}),
method: "POST",
});
// レスポンスが200の場合にのみ、メール送信処理を実行
if (responce_server.status === 200) {
//ここにメール送信の処理
} else {
//ここにエラー時の処理
}
};
return
//省略
};
};
export default Contact;
以上、reCAPTCHA v3の実装方法でした。
それではまた。
HTNCode