開発情報・ナレッジ

投稿者: SPIRERS ナレッジ向上チーム 2022年3月11日 (金)

フォームにreCAPTCHAを設定する

reCAPTCHAとはスパムやbotなどによる悪質なアクセスからWebサイトを保護するための仕組みです。
Googleが提供するreCAPTCHAをSPIRALver1で作成したフォームに組み込むことができます。

DEMOはこちら
reCAPTCHAの制御方法は複数ありますが、
ここではreCAPTCHAチェックを入れた際にボタンが有効化になる方法をご紹介します。

reCAPTCHA設定(Google側)

まずGoogleのreCAPTCHAページにてサイトドメインを登録し、サイトキー・シークレットキーを取得します。

1.Google reCAPTCHAページ
Google reCAPTCHAページ
にアクセスし、右上の「Admin console」をクリックします。

2.サイトの登録
・reCAPTCHAタイプの項目は「reCAPTCHA v2」を選択します。
・ドメインはSPIRAL ver.1で作成したフォームURLの「reg○○.smp.ne.jp」部分を設定します。
※○○部分はSPIRAL ver.1システムごとに変わりますのでご注意ください。

(サイトの登録画面)


3.サイトキー、シークレットキーの取得
上記の登録が終わると、サイトキーとシークレットキーが表示されますので控えておきます。

(サイトキー、シークレットキーの取得画面)

サイトキー、シークレットキーをカスタムモジュールに保存

シークレットキーはフォームとreCAPTCHA 間の通信で使用する重要なキーとなるため、
カスタムモジュールなど外部からアクセスできない場所に保管してrequire などを使って読み込むことをおすすめします。
サイトキーもまとめておくと変更があった場合の管理の際に便利です。
カスタムモジュールの設定方法は下記サポートサイトよりご確認ください。
カスタムモジュール
カスタムモジュールに設定するサンプルPHPスクリプトは下記です。
<?php

// reCAPTCHA v2 サイトキー
define('V2_SITEKEY', '取得したサイトキー');
// reCAPTCHA v2 シークレットキー
define('V2_SECRETKEY', '取得したシークレットキー');

?>

フォーム入力HTMLソースにカスタムモジュールを呼び出すPHPコード、reCAPTCHAチェックタグ、reCAPTCHA API読み込みタグを設置

フォーム入力HTMLソースにカスタムモジュールの呼び出しとセッションの初期化をするPHPコードを設置します。
設置場所はHTMLソースの最初の行に設置します。
なお、1行目はSPIRALでPHPを使用する際に必要なタグとなるため必ず記載します。
<?php // <!-- SMP_DYNAMIC_PAGE DISPLAY_ERRORS=OFF NAME=check --> ?>
<?php
require 'カスタムモジュールの実行時ファイルパス';
// reCAPTCHA サイトキー
$siteKey = V2_SITEKEY;

// セッションを初期化
$session = $SPIRAL->getSession();
$session->remove("recaptcha_result");
?>
reCAPTCHAチェックタグを任意の場所に設置します。
デモフォームでは判定タグ「<input type="hidden" name="detect" value="判定">」直前に設置しています。
<div class="g-recaptcha" data-sitekey="取得したサイトキー" data-callback="verifyCallback" data-expired-callback="expiredCallback"></div>
<p id="warning">送信するにはチェックを入れてください。</p>
form閉じタグ直前にreCAPTCHA の API読み込みタグを設置します。
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

フォーム入力HTMLソースにボタンが有効になるJavaScriptを設置

チェックが入ったらボタンが有効になるJavaScriptをhead閉じタグ直前に設置します。
<script> 
  var verifyCallback = function(response) { //コールバック関数の定義
    //#warning の p 要素のテキストを空にf
    document.getElementById("warning").textContent = '';
    //#send の button 要素の disabled 属性を解除
    document.getElementById("send").disabled = false;
  };
  var expiredCallback = function() { //コールバック関数の定義
    //#warning の p 要素のテキストに文字列を設定
    document.getElementById("warning").textContent = '送信するにはチェックを・・・';
    //#send の button 要素に disabled 属性を設定
    document.getElementById("send").disabled = true;
  };
</script>
ボタンタグに「id="send"」と無効化になる「disabled」を設置します。
<input class="submit" type="submit" name="submit" value="送信" id="send" disabled>

フォーム確認HTMLソースにPHPコードを設置

reCAPTCHAを実装したフォームから送られてきたデータを処理する前に認証コードが正しいか不正かを判定するため、フォーム確認HTMLソース上に判定するためのPHPコードを設置します。
判定後にreCAPTCHAの判定が問題なかった場合はセッションにフラグをセットします。
なお、SPIRALではセキュリティの関係上file_get_contents()の利用を禁止しているため、通信にはcURL関数を使います。

下記サンプルコードです。
<?php // <!-- SMP_DYNAMIC_PAGE DISPLAY_ERRORS=OFF NAME=confirm --> ?>
<?php
require 'カスタムモジュールの実行時ファイルパス';
// reCAPTCHA サイトキー
$siteKey = V2_SITEKEY;
// reCAPTCHA シークレットキー
$secretKey = V2_SECRETKEY;

$result_status = '';  // 結果を表示する文字列を初期化

if (isset($_POST['g-recaptcha-response'])) {

    // 配列なら最初の要素、文字列ならそのまま使用
    $token = $_POST['g-recaptcha-response'];

    if (is_array($token)) {
        $token = reset($token);
    }

    // cURL セッションを初期化
    $ch = curl_init();
  // curl_setopt() により転送時のオプションを設定
  //API の URL の指定
  curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
  //HTTP POST メソッドを使う
  curl_setopt($ch, CURLOPT_POST, true );
  //API パラメータの指定
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
        'secret'   => $secretKey,
        'response' => $token
    )));
  //curl_execの返り値を文字列にする
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  //転送を実行してレスポンスを $json に格納
    $json = curl_exec($ch);
  //セッションを終了
    curl_close($ch);

  //レスポンスの $json(JSON形式)をデコード
    $result = json_decode($json);
    $session = $SPIRAL->getSession();

    if (!empty($result->success)) {
        $result_status = '成功';
        $session->put("recaptcha_result", "OK");
    } else {
        $result_status = '失敗:';

        if (!empty($result->{'error-codes'})) {
            $result_status .= $result->{'error-codes'}[0];
        }
        $session->remove("recaptcha_result");
    }
}
?>

フォームサンキューHTMLソースにPHPコードを設置

登録前に確認画面を通りreCAPTCHAの判定を通ったことを確認するため、フォームサンキューHTMLソースにPHPコードを設置します。

下記サンプルコードです。
<?php // <!-- SMP_DYNAMIC_PAGE DISPLAY_ERRORS=OFF NAME=thanks --> ?>
<?php
$session = $SPIRAL->getSession();
if($session->get("recaptcha_result") == "OK") {
  $result_status = '成功';
} else {
  $result_status = '失敗:';
}
?>

ステータス確認用タグを設置

成功/失敗のステータスを確認する場合は確認画面と完了画面で「$result_statu」の中身を表示することで確認可能です。画面に表示されるため、テスト後は削除してください。

下記サンプルコードです。
ステータス:<?= $result_status; ?>
以上でreCAPTCHA設定は完了です。
WebToolsでの設定方法は下記ページをご覧ください。
reCAPTCHA設定

不具合やほかのやり方が知りたい等あれば、下記の「コンテンツに関しての要望はこちら」からご連絡ください。
また今回は以下ページを参照させていただきました。
Google reCAPTCHA の使い方(v2/v3)

解決しない場合はこちら コンテンツに関しての
要望はこちら