事前準備
- reCAPTCHAのサイト登録をしておく → https://www.google.com/recaptcha/admin
- 発行されたサイトキーとシークレットキーをメモ
フロント
-
react-google-recaptcha-v3
を入れて、GoogleReCaptchaProvider
で囲っておく - サイトキーは環境変数から読み込む
<GoogleReCaptchaProvider
reCaptchaKey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY!} // ← サイトキー
>
{props.children}
</GoogleReCaptchaProvider>
- reCAPTCHAを使いたいところで ↓ の処理を行う
Component.tsx
const { executeRecaptcha } = useGoogleReCaptcha();
...
const onClick = () => {
if (executeRecaptcha == null) return;
const serverEndpoint = '/api/mail';
const token = await executeRecaptcha('任意の名前');
const postData = await fetch(serverEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'g-recaptcha-response': token,
mailTo: 'mailTo@test.com',
body: '本文',
}),
});
}
※ GoogleReCaptchaProvider
よりも下の階層のコンポーネント内でないと、executeRecaptcha
がundefinedになり失敗する
バックエンド
- 環境変数に
RECAPTCHA_SECRET
を入れておく - .htaccess使うなら↓
.htaccess
SetEnv RECAPTCHA_SECRET 'reCaptcha v3 secret'
- APIを実装する
/api/mail.php
<?php
$secretKey = getenv("RECAPTCHA_SECRET"); // ← シークレットキー
$json_data = file_get_contents("php://input");
$decoded_data = json_decode($json_data);
$token = $decoded_data -> {"g-recaptcha-response"};
// reCAPTCHA
$url = "https://www.google.com/recaptcha/api/siteverify";
$data = array(
"secret" => "$secretKey",
"response" => "$token",
);
$data = http_build_query($data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $data
)
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
if(!json_decode($response, true)["success"]) {
// 検証失敗
echo json_encode(["result" => "failed"]);
exit();
}
// 検証成功
mb_language("Japanese");
mb_internal_encoding("UTF-8");
date_default_timezone_set('Asia/Tokyo');
// メール全般設定
$mailTo = $decoded_data -> mailTo;
$subject = "【お問い合わせ】フォームよりお問い合わせがありました";
$header = "From: no-reply@test.com"."\r\n"
."Return-Path: no-reply@test.com";
// フォーム項目を取得
$message = $decoded_data -> body;
// 送信
mb_send_mail($mailTo, $subject, $message, $header);
// 結果出力
echo json_encode(["result" => "success"]);
※ 迷惑メール判定を受けないようDNSのSPFレコードも設定しておく
※ APIと同じサーバー内のメールサーバーから送る想定になっているので、別サーバーを使用する際はSMTPで送るように変える