9
5

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.

Google reCAPTCHA v2の設定をしてみた

Last updated at Posted at 2022-08-31

はじめに

とある日からお問合せフォームからスパムメールが大量に送られてくるようになりました。
qq.comのドメインから中国後で書かれた解読不能なメールが1分間に何10件も、、、

その対策として導入したキャプチャ認証のreCAPTCHAを入れてからスパムメールはピタリと止まりました。
今回はそのreCAPTCHAの設定方法の共有記事になります。

やること

おおまかにですが、以下を対応します。
・reCAPTCHAにサイトを登録
・HTML上の実装
・PHPを使った検証

reCAPTCHAにサイトを登録

reCAPTCHA-3.png

ラベル

これは識別用に管理しやすい名前を入れます

reCAPTHAタイプ

今回はreCAPTHAタイプをv2を選択
「私はロボットではありません」チェックボックスを選択

ドメイン

認証を入れたドメインを入れる

オーナー

オーナーは自分だけであればそのままでOK

送信まで

利用条件に同意してアラートにオーナーに送信するかどうかを選び
最後に「送信」を押下

API キー取得

入力に問題がなければ、APIキー(サイトキーとシークレットキー)が表示されるのでコピーしておきます。APIキーは recaptcha/admin で後から確認することができます。

Site Key : reCAPTCHAを表示する際に使用するサイトのキー
Secret Key : 検証で使用する秘密のキーで公開してはいけません。

これでサイト登録は完了!

HTML上の実装

スクリーンショット 2022-08-31 21.25.09.png

今回はこのように作成しましたという一例です。

g-recaptchaタグを使って表示

<html lang="ja">
<head>
<title>g-recaptcha タグを使って表示</title>
<script> 
  var verifyCallback = function(response) { //コールバック関数の定義
    //#warning の p 要素のテキストを空に
    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>
</head>
<body>
  <h1>g-recaptcha タグを使って表示</h1>
  <form method="post" action="?">
    <div class="g-recaptcha" data-sitekey="サイトキー" data-callback="verifyCallback" data-expired-callback="expiredCallback"></div>
    <p id="warning">送信するにはチェックを入れてください。</p>
    <button id="send" type="submit" disabled>送信</button>
  </form>
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</body>
</html>

サイトキーのところには先ほど取得した Site Key を入れてください

この記述で見た目上のチェックボックスが出来上がりました。

g-recaptcha-response(レスポンス)

ユーザがウィジェットにチェックを入れて成功すると、API により以下のようなレスポンス(トークン)が生成されます。

03AERD8Xr85M-qcg5EoivhRUI9RgNagFmqwGUKZcXupYI_2tcBLncMtupBlxGiT4C0YYOUI7R4k3o
NX4OCYI9kq83tmTqG1MuNEIexHli-qNd5FLE7XKpOi3Tliy5ZVUFmaeg1qwCnzGUKn1Pd7ae79xn
・・・中略・・・
PEn1Pd7ae9fX_aeg1fNQME9mNNCnzMp8_ATvQ

この値を使ってサーバ側で検証を行います。この値は以下の方法で取得することができます。

コールバック関数のパラメータ: function(response) の response
grecaptcha.getResponse メソッド(返り値)
フォームを送信した際に生成される $_POST["g-recaptcha-response"]
このレスポンス(g-recaptcha-response)はトークンとも呼ばれ、有効期間は2分間です。

今回はフォームを送信した際に生成される $_POST["g-recaptcha-response"]を使ってPHPで検証します。

PHPを使った検証

reCAPTCHA を設置しただけでは意味がないので、サーバ側でレスポンスがユーザにより生成されたものかを検証する必要があります。

以下のような流れで判定します。
・ユーザのレスポンス(トークン)を取得($_POST[ 'g-recaptcha-response' ])
・API を使ってトークンを検証(API にトークンを送信して検証結果を取得)
・API から取得した値(検証結果)を基に判定

フォーム送信後の完了画面などでPHPで実装しました。

  $recaptcha = $_POST['g-recaptcha-response'];
  if (isset($recaptcha)) {
      $captcha = $recaptcha;
  } else {
      $captcha = '';
  }
  $secretKey = "シークレットキー";
  $url="https://www.google.com/recaptcha/api/siteverify?secret={$secretKey}&response={$captcha}";
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt( $ch, CURLOPT_URL, $url );
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
  $result = curl_exec( $ch );
  curl_close($ch);

  $resp_result = json_decode($result,true);
  if(intval($resp_result["success"]) !== 1) {
    // reCAPTCHA承認失敗時の処理
    header('Location: サイトURL');
    exit;
  }

シークレットキーのところには先ほど取得した Secret Key を入れてください
サイトURLのところには設定したい失敗時の遷移先をいれてください(エラーメッセージを出すに変えてもいいですね)

file_get_contents() か cURL 関数を使って取得できます。
今回は cURL 関数を使いました。

これで設定完了になります。

結果確認

reCAPTCHA-4.png

検証の結果を受け取れています。
目的はスパムメール対策でしたがこれで綺麗に止まったためひとまず安心です。

参考

https://www.webdesignleaves.com/pr/plugins/google_recaptcha.php
https://www.hai2mail.jp/column/2020/0509.php

9
5
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
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?