お問い合わせフォームからのスパム送信に悩まされていませんか?多くの中小企業では、ウェブサイトのフォーム経由で大量の不要なメッセージやボットによる自動送信に対処する必要があります。これらは業務効率を下げるだけでなく、セキュリティリスクにもなり得ます。
Googleが提供するGoogle reCAPTCHA v2でこの問題を簡単に解決できます。特にReactで構築したフォームに簡単に導入でき、技術的な専門知識が限られた中小企業でも実装可能です。このガイドでは、ReactフォームにGoogle reCAPTCHA v2を導入する具体的な手順を解説します。
今回は、スパム対策の重要性、実装手順、gasでのスパム検証方法まで段階的に説明します。この記事を参考に、お問合せフォームをより安全で効率的なものに改善しましょう。
お問合せフォームにGoogle reCAPTCHA v2を導入する理由とメリット
お問合せフォームに適切なスパム対策を施すことは、現代のウェブ開発において必須の課題となっています。なぜGoogle reCAPTCHA v2が効果的な選択肢なのか、簡単に説明します。
スパム防止にreCAPTCHAが有効な理由
フォームスパムは単なる迷惑以上の問題です。企業にとって、大量のスパムメールは以下のような深刻な影響をもたらします:
Google reCAPTCHAは「Completely Automated Public Turing test to tell Computers and Humans Apart(コンピュータと人間を区別するための完全自動化された公開チューリングテスト)」の略で、その名の通り人間とボットを区別します。画像認識チャレンジやチェックボックスなどのインタラクションを通じて、自動送信ボットをブロックしながら、実際のユーザーには最小限の負担で認証を完了させることができます。
Google reCAPTCHA v2とv3の違い
Google reCAPTCHAには主にv2とv3の2つのバージョンがあり、それぞれ特徴が異なります:
reCAPTCHA v2:
reCAPTCHA v3:
reCAPTCHA v2を選ぶべき理由
今回は、reCAPTCHA v2を実装導入する手順をご紹介します。わたしが、reCAPTCHA v2を選んだ理由は主に以下です。
reCAPTCHA v3は高度なセキュリティを提供しますが、スコアの閾値設定や誤判定時の対応など、より専門的な知識と継続的な監視が必要です。最小限のリソースで導入&運用を目指すなら、v2の方が費用対効果に優れた選択と考えました。
GASのエンドポイントが誰にでも公開されていることが危険な理由
前回の記事で、Google Apps Script(GAS)をフォーム送信先として利用する手順をご紹介しました。GASをフォームの送信先としてするためにWEBアプリとしてデプロイする必要があります。記事内でも軽く触れましたがこの方法はセキュリティリスクが潜んでいます:
reCAPTCHAを実装することで、正規のユーザーからの送信のみをバックエンドで処理するよう制限でき、このリスクを大幅に軽減できます。特にGASエンドポイントを使用している場合、reCAPTCHAによる検証は不可欠なセキュリティ層となります。
お問合せフォームにGoogle reCAPTCHA v2を組み込む手順と実装方法
reCAPTCHA v2をReactフォームに導入する具体的な手順を見ていきましょう。技術的な知識が限られている方でも、以下のステップに従うことで安全に実装できます。
Google reCAPTCHAのサイトキー・シークレットキーを取得する
まず、reCAPTCHAを使用するために必要なキーを取得します:
- Google reCAPTCHA管理コンソールにアクセスします(Googleアカウントでログインが必要)
- 「新しいサイトを登録」ボタンをクリックします
- 以下の情報を入力します:
- 利用規約に同意し、「登録」ボタンをクリックします
- 登録完了画面で表示される「サイトキー」と「シークレットキー」を安全に保存します
サイトキーとシークレットキーは、それぞれフロントエンドとバックエンドでreCAPTCHAの検証に使用されるため、安全に管理することが重要です。
react-google-recaptchaライブラリをインストールする
Reactプロジェクトで簡単にreCAPTCHAを実装するために、専用のライブラリをプロジェクトにインストールします:
# npmの場合
npm install react-google-recaptcha --save
# yarnの場合
yarn add react-google-recaptcha
このライブラリは、GoogleのreCAPTCHA v2をReactコンポーネントとして提供し、フォームへの統合を簡素化します。
フォームにreCAPTCHAを設置してトークンを取得する
次に、Reactコンポーネント内でreCAPTCHAを実装します:
import React, { useState, useRef } from 'react';
import ReCAPTCHA from 'react-google-recaptcha';
const ContactForm = () => {
const [formData, setFormData] = useState({
name: '',
email: '',
message: ''
});
const [captchaToken, setCaptchaToken] = useState(null);
const recaptchaRef = useRef(null);
// 入力フィールドの変更を処理する関数
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prevState => ({
...prevState,
[name]: value
}));
};
// reCAPTCHAの変更を処理する関数
const handleCaptchaChange = (token) => {
setCaptchaToken(token);
};
// フォーム送信時の処理
const handleSubmit = async (e) => {
e.preventDefault();
// captchaTokenがnullの場合、検証が完了していないためアラートを表示
if (!captchaToken) {
alert('「私はロボットではありません」にチェックを入れてください');
return;
}
// このあとの送信処理は後ほど実装
console.log('フォームデータ:', formData);
console.log('reCAPTCHAトークン:', captchaToken);
};
return (
<form onSubmit={handleSubmit} className="contact-form">
<div className="form-group">
<label htmlFor="name">お名前</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="email">メールアドレス</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="message">お問い合わせ内容</label>
<textarea
id="message"
name="message"
value={formData.message}
onChange={handleChange}
required
rows="5"
></textarea>
</div>
<div className="recaptcha-container">
<ReCAPTCHA
ref={recaptchaRef}
sitekey="あなたのサイトキーをここに入力"
onChange={handleCaptchaChange}
hl="ja" // 日本語表示にする場合
/>
</div>
<button type="submit" className="submit-button">送信する</button>
</form>
);
};
export default ContactForm;
このコードでは、reCAPTCHAコンポーネントを追加し、ユーザーが「私はロボットではありません」をクリックするとトークンが生成され、captchaToken
ステートに保存されます。フォーム送信時にこのトークンがない場合は送信をブロックします。
送信時にreCAPTCHAトークンをAPIに渡す方法
フォーム送信時に、reCAPTCHAトークンをバックエンドAPIに送信して検証する方法を実装します:
// 先ほどのhandleSubmit関数を拡張
const handleSubmit = async (e) => {
e.preventDefault();
// captchaTokenがnullの場合、検証が完了していないためアラートを表示
if (!captchaToken) {
alert('「私はロボットではありません」にチェックを入れてください');
return;
}
// 送信中状態を管理する場合
setIsSubmitting(true);
try {
// FormDataオブジェクトの作成
const dataToSend = {
...formData,
recaptchaToken: captchaToken // reCAPTCHAトークンを含める
};
// APIエンドポイントへのPOSTリクエスト
const response = await fetch('あなたのAPIエンドポイントURL', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(dataToSend)
});
const result = await response.json();
if (response.ok) {
// 送信成功時の処理
alert('お問い合わせを送信しました。ありがとうございます。');
// フォームのリセット
setFormData({ name: '', email: '', message: '' });
// reCAPTCHAのリセット
recaptchaRef.current.reset();
setCaptchaToken(null);
} else {
// エラーメッセージの表示
alert(`エラーが発生しました: ${result.error || '不明なエラー'}`);
}
} catch (error) {
console.error('送信エラー:', error);
alert('送信中にエラーが発生しました。後ほど再度お試しください。');
} finally {
setIsSubmitting(false);
}
};
このコードでは、フォームデータと一緒にreCAPTCHAトークンをバックエンドに送信します。バックエンドでこのトークンの有効性を検証することで、人間からの正当なリクエストであることを確認できます。
ReactフォームにGoogle reCAPTCHA v2を導入して安全性を高めよう
ここまでの実装により、ReactフォームにGoogle reCAPTCHA v2が正常に統合されました。この導入によって得られるメリットは大きく、スパムボットからの自動送信を効果的に防止しながら、実際のユーザーには最小限の負担でフォームを利用してもらうことができます。
追加のカスタマイズとして、以下のようなオプションも検討できます:
また、reCAPTCHAは定期的にトークンが失効するため、長時間フォームを開いたままにしていると有効期限が切れることがあります。この場合、送信前に再度検証が必要になるため、エラーメッセージで適切にユーザーに案内することも重要です。
Google Apps Scriptやバックエンド側でのreCAPTCHA検証方法(任意)
フロントエンドでreCAPTCHAを実装するだけでは完全なセキュリティは確保できません。バックエンド側(受け取り側)での検証が不可欠です。ここでは概要を紹介します。
トークン検証に使うGoogleのAPIエンドポイント
Google reCAPTCHAトークンの検証には、Googleが提供する専用APIエンドポイントを使用します:
https://www.google.com/recaptcha/api/siteverify
このエンドポイントにPOSTリクエストを送信し、以下のパラメータを含める必要があります:
レスポンスは以下のようなJSON形式で返されます:
{
"success": true|false,
"challenge_ts": "タイムスタンプ",
"hostname": "ユーザーがreCAPTCHAを解いたサイトのホスト名",
"error-codes": ["エラーコードの配列(エラー時のみ)"]
}
success
フィールドがtrue
の場合のみ、トークンが有効であると判断できます。
GAS側での検証例(MailApp送信前のチェック)
Google Apps Script(GAS)でreCAPTCHAを検証する基本的な例を示します:
function doPost(e) {
// POSTリクエストからデータを取得
const data = JSON.parse(e.postData.contents);
const { name, email, message, recaptchaToken } = data;
// reCAPTCHAトークンの検証
const recaptchaVerification = verifyRecaptcha(recaptchaToken);
// 検証に失敗した場合はエラーレスポンスを返す
if (!recaptchaVerification.success) {
return ContentService.createTextOutput(JSON.stringify({
success: false,
error: 'reCAPTCHA検証に失敗しました'
})).setMimeType(ContentService.MimeType.JSON);
}
try {
// 検証成功後にメール送信など処理を実行
MailApp.sendEmail({
to: "your-email@example.com",
subject: "ウェブサイトからのお問い合わせ",
body: `名前: ${name}\nメールアドレス: ${email}\n\nメッセージ:\n${message}`
});
// 成功レスポンスを返す
return ContentService.createTextOutput(JSON.stringify({
success: true,
message: 'お問い合わせを送信しました'
})).setMimeType(ContentService.MimeType.JSON);
} catch (error) {
// エラーレスポンスを返す
return ContentService.createTextOutput(JSON.stringify({
success: false,
error: error.toString()
})).setMimeType(ContentService.MimeType.JSON);
}
}
// reCAPTCHAトークンを検証する関数
function verifyRecaptcha(token) {
const SECRET_KEY = "あなたのシークレットキーをここに入力";
// Google reCAPTCHA検証APIにリクエスト
const response = UrlFetchApp.fetch("https://www.google.com/recaptcha/api/siteverify", {
method: "post",
payload: {
secret: SECRET_KEY,
response: token
}
});
// レスポンスをJSONとしてパース
return JSON.parse(response.getContentText());
}
このスクリプトでは、フロントエンドから受け取ったreCAPTCHAトークンをGoogle APIで検証し、有効な場合のみメール送信などの処理を実行します。
成功/失敗時の応答の扱い方と注意点
バックエンド側での検証結果に応じた適切な対応が重要です:
成功時:
失敗時:
注意点:
適切なエラーハンドリングと安全なトークン検証により、スパム対策の効果を最大化しながらユーザー体験を損なわないバランスを実現できます。
以下にまとめの部分のみを出力します:
Google reCAPTCHAのコストに関する部分を追加します。以下がその部分のみの出力です:
Google reCAPTCHAの導入コストとランニングコスト
reCAPTCHA v2を導入する際のコスト面も重要な検討ポイントです。中小企業にとって嬉しいことに、通常の使用であれば以下のようなコスト構造となっています:
初期導入コスト:
ランニングコスト:
小規模事業では、月間の問い合わせ数が数百から数千程度であることを考えると、無料枠で十分対応可能です。
注意点として、reCAPTCHA Enterprise(企業向け高度バージョン)を利用する場合は別料金体系となりますが、通常の中小企業であれば標準バージョンで十分な機能とセキュリティレベルを確保できます。
まとめ
本記事では、React実装したお問合せフォームにGoogle reCAPTCHA v2を導入する方法について解説しました。ウェブサイトを公開する上で、スパム対策は業務効率化とセキュリティ強化の両面で重要な課題です。reCAPTCHA v2は、実装の容易さと効果的なスパム防止機能を兼ね備えた理想的なツールです。
サイトキーとシークレットキーの取得から始まり、react-google-recaptcha
ライブラリを使ったフロントエンド実装、そしてバックエンドでの検証まで、一連の流れを理解することで、技術的な専門知識が限られていても導入することが可能です。
特に重要なのは、フロントエンドだけでなくバックエンド側での検証も必ず実装することです。これにより、フォームをバイパスした不正なAPIリクエストからもシステムを守ることができます。
reCAPTCHA v2の導入により、本当に必要なお問い合わせだけを受け取り、業務効率を向上させながら、ウェブサイトのセキュリティを強化しましょう。小さな対策が、大きな安心につながります。