1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React + PHPでreCAPTCHAv3を使いつつメールを送信するサンプル

Last updated at Posted at 2023-12-14

事前準備

フロント

  • 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で送るように変える

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?