9
14

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 3 years have passed since last update.

reCAPTCHA v3 × Laravel

Posted at

#Laravel5.7にreCAPTCHAv3を導入する手順
v3導入にあたって、

anhskohbo/no-captcha
ARCANEDEV/noCAPTCHA
どちらのライブラリを使えば良いの??問題

(結論としては今回はARCANEDEV/noCAPTCHA
になります。これはLaravelの4.2~7.xまでサポートしているようなので、今回は5.7で検証していますが、他のバージョンでも同様にいけるはずです。)


reCAPTCHAのトークンは二分間しか持たない問題

Note: reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action.
Google reCAPTCHA

上記2点に主に焦点を当てて導入手順を述べていきたいと思います。

##目次

  1. reCAPTCHAとは?
  2. サイトキー(SITEKEY)とシークレットキー(SECRETKEY)の取得
  3. composerでライブラリをインストール
  4. フロントエンド
  5. バックエンド


###reCAPTCHAとは?
Google reCAPTCHA
人間になりすましてBOTが操作していないかチェックしてくれる,Googleのサービス。
「私はロボットではありません」のあれです。

このreCAPTCHA
v1,v2 とあるなかで 2018/10/29からv3になっています。
v2とv3の違いについてはググるとすぐにわかるのでここでは省きますが、
ユーザーがチェックを入れる必要がなくなったという事実はv3導入において一つのポイントになります。


###サイトキー(SITEKEY)とシークレットキー(SECRETKEY)の取得
Google reCAPTCHA Developer's Guide
↑ここに大まかな実装方法は書いてあります

サイトキー(SITEKEY)とシークレットキー(SECRETKEY)の取得はこちらから
↑ここにreCAPTCHAを適用したいサイトを載せます。
主な各項目について
ラベル :
ここはサイトに対するニックネーム的扱いです。(自分がわかればなんでも良いです。)
reCAPTCHAタイプ :
今回はv3を利用するのでv3にチェックを入れます。
ドメイン :
普通にドメインを登録すれば良いのですが、開発環境で確認したい場合はlocalhostではなく、

127.0.0.1

で登録をして進めてください。

これで登録が完了すると
・サイトキー(SITEKEY)
・シークレットキー(SECRETKEY)
が発行されます。
あとはライブラリと組み合わせて
実装を進めます。


###composerでライブラリのインストール
ARCANEDEV/noCAPTCHA
をcomposerでインストールします。
Laravelのバージョンに応じてnoCAPTCHAのインストールのバージョンを確認してください
今回はLaravel5.7なので

composer require arcanedev/no-captcha:8.x

インストールしたら

php artisan vendor:publish --provider="Arcanedev\NoCaptcha\NoCaptchaServiceProvider"

でno-captchaのconfigファイルを呼び出して、
versionを示す部分がv3になっているか確認をします。(私はデフォルトでv3になっておりました。)

その後、先ほど所得した
SITEKEYとSECRETKEYを
.envファイルに

NOCAPTCHA_SECRET=your-secret-key
NOCAPTCHA_SITEKEY=your-site-key

と記述してセット


###フロントエンド
Google reCaptcha フロントエンド
↑公式の参照ページはこちら
公式にはざくっとこんな感じのことが記述されています。

  1. Load the JavaScript API with your sitekey.
  2. Call grecaptcha.execute on an action or when the page loads.
  3. Send the token immediately to your backend with the request to verify.

1.まずJavaScript APIを読み込んでください。
2.イベント発火かあるいは、ページがロードされる際、"grecaptcha.execute"を呼び出すよう記述してください
3.すみやかにバックエンドにrequestと一緒にトークンを送り込んでください。

なんとなくここを意識しながらフロントエンドの実装にうつります。

form.blade.php
<form id="form" action="{{ route('post')}}" method="POST">


    <button type="subbmit" id="form_btn">送信</button>
</form>

今回はNoCaptchaを使った時の書き方を以下に記述します。

reCAPTCHAを適用したいformの中に

form.blade.php
<form id="form" action="{{ route('post')}}" method="POST">

    {!! no_captcha()->input() !!}

    <button type="subbmit" id="form_btn">送信</button>
</form>

と記述します。
これは以下とまったく同じ意味です。

<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">

あとで、javascriptこのinputタグに対して
valueにトークンをセットしてあげます。

そして</body>付近に

form.blade.php
{!! no_captcha()->script() !!} 

これは以下と同じ意味になります。


<script src="https://www.google.com/recaptcha/api.js?hl=jp&amp;render=SITE_KEY"></script>

v3のreCAPTCHAのイメージと、SITE_KEYをAPIに投げることで、当サイトがreCAPTCHAの保護対象かどうかを判断しています。

そして今回のポイントの一つ
reCAPTCHAのトークンは二分間しか持たない問題

Note: reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action.

ここをクリアするために
少しjavascriptで工夫を懲らします。


$(function () {
    $('#form_btn').on('click',function (e){
        if(confirm('本当に送信してもよろしいですか?')){
            e.preventDefault();
            grecaptcha.ready(function() {
                grecaptcha.execute('取得したサイトキー', {action: 'login'}).then(function(token) {
                    $('#g-recaptcha-response').val(token);
                    //ここでトークンを渡す。
                    $('#form').submit();
                });
            });    
        }
    });
});


###バックエンド
Google Recapcha バリデーション
↑ここにバリデーションの方法など書いてます。
取得したSECRETKEYを用いて色々する必要があるのですが、
このあたりは
ARCANEDEV/noCAPTCHA
がとても楽にしてくれています。

私たちがやるべきことはコントローラでValidatorを利用してバリデーションルールを追加すれば良いだけ。

FormController.php
        $requests = $request->all();
        $rules = [
                // other 他のバリデーションルール
            'g-recaptcha-response' => ['required',new CaptchaRule] //ここではrequiredとcaptchaを設定しております。
        ];
        $messages = [
             // 他にも
            'g-recaptcha-response.captcha' => 'reCaptchaによってうまく認証されませんでした'
        ];
        $validator = Validator::make($requests, $rules, $messages)->validate();

・requiredはトークンがセットされているかどうか
・captchaはトークンが有効かどうか

これで実装完了です。

###ちなみに…
anhskohbo/no-captcha
でも試したのですが、こちらでは私ではうまくできませんでした。
・READMEに、v3のサポートが明記されない
・インストールしてみましたが、参照URLがv2のものになっていた

もしかしたらconfigファイルをいじったりしたらうまくできるのかもしれませんが、それはまたの機会に。
PHP用にGoogleからもライブラリが出ているようなので今度はそちらでも試してみたいところです。

Qiita初投稿です。
記述に不備があればご指摘くださいますようよろしくお願いいたします。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?