どうもこんにちは。
ボット対策でおなじみ(?)のreCAPTCHAをLaravelのログインページに入れてみよう!
ということで、その手順です。
一応、v2もv3もやってみています。
相変わらず、Laravelの話はバージョン5.8でお送りします。
# LTSな6.0が出てるし、バージョンアップも考えなきゃ。。。
では、始めましょう。
目次
Admin Consoleに登録
reCAPTCHAのAdmin Consoleから、サイトを登録しましょう。
https://www.google.com/recaptcha/intro/v3.htmlにアクセスすると、
右上にAdmin Consoleボタンがあるので、それをクリック。

すると、新しいサイトを登録しなさいと言われます。
適宜登録しましょう。

reCAPTCHA タイプでバージョンを指定します。
また、ドメインには設置するサイトのドメインを記入します。
localhostも設定可能です。
あとは利用規約に同意して、送信ボタンをクリック。

登録できました。この画面に出てきている「サイトキー」と「シークレットキー」を控えておきましょう。
では、次。
モジュールをインストール
みんな大好きComposerで、必要なモジュールをインストールします。
今回は、「noCAPTCHA」を使いました。
v2、v3両方とも対応していて、Laravel 6.0にも対応している(!)ということで
ありがたく利用します。
詳しくはコチラ ⇒ ARCANEDEV/noCAPTCHA
公式に、インストール方法とか、きちんとドキュメントがあるので
迷うことはないと思いますが。
composer require arcanedev/no-captcha
Laravelのバージョンによって、noCAPTCHAのバージョンを適切なものに指定しましょう。
詳しくは公式で。
インストールが終われば、Laravel本体の設定です。
Laravelの設定
これも公式に記載されている内容ですが。。。
config/app.php
Laravel のバージョンが 5.4 以下の場合、providers に追加する必要があるんですが、
今回は5.8のため、割愛します。
.env
.envファイルに、admin Consoleで表示されたサイトキーとシークレットキーを記述します。
私はこんな感じにしました。
| 
					 1 2  | 
						NOCAPTCHA_SECRET=[シークレットキー] NOCAPTCHA_SITEKEY=[サイトキー]  | 
					
noCAPTCHA設定ファイル(config/no-captcha.php)
noCAPTCHAの設定ファイルをプロジェクト内に移します。
コマンドを実行しましょう。
php artisan vendor:publish --provider="Arcanedev\NoCaptcha\NoCaptchaServiceProvider"
コレでconfig/no-captcha.phpが出来上がります。
あとは、適宜編集すればよいのですが、少なくともバージョンは気にしておきましょう。
| 
					 1 2 3 4 5 6 7 8 9  | 
						return [     'secret'  => env('NOCAPTCHA_SECRET', 'no-captcha-secret'),     'sitekey' => env('NOCAPTCHA_SITEKEY', 'no-captcha-sitekey'),     'version' => 'v3', // <- v2を使うなら、'v2'にする。     'lang' => 'jp',     'skip-ips' => [         // 127.0.0.1     ], ];  | 
					
はい。あとは実装です。
実装
実装で注意が必要なのは、ViewとValidationです。
View
v2とv3で、少しだけ内容が違うので、注意しましょう。
◇v2の場合
v2のスクリプトをロードするために、{!! no_captcha()->script() !!}を追加します。
また、formタグの中に、{!! no_captcha()->display() !!}を追加します。
あ、今回v2はチェックボックスのやつを使ってます。
他のは試してないです。。。
こんな仕上がりでよいかと。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | 
						<form method="POST" action="{{ route('login') }}">     @csrf     (中略)     <div class="form-group row">         <div class="col-md-6 offset-md-4">             <div class="form-check">                 {!! no_captcha()->display() !!}             </div>         </div>     </div>     <div class="form-group row mb-0">         <div class="col-md-8 offset-md-4">             <button type="submit" class="btn btn-primary">                 {{ __('Login') }}             </button>         </div>     </div> </form> {!! no_captcha()->script() !!}  | 
					
◇v3の場合
v3のスクリプトをロードするために、
{!! no_captcha()->script() !!}
{!! no_captcha()->getApiScript() !!}と、sctiptのコード
| 
					 1 2 3 4 5 6 7  | 
						    <script>         grecaptcha.ready(function() {             window.noCaptcha.render('login', function (token) {                 document.querySelector('#g-recaptcha-response').value = token;             });         });     </script>  | 
					
を追加します。
また、formタグの中に、{!! no_captcha()->input() !!}を追加します。
こんなところです。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21  | 
						<form method="POST" action="{{ route('login') }}">     @csrf     (中略)     <div class="form-group row mb-0">         <div class="col-md-8 offset-md-4">             <button type="submit" class="btn btn-primary">                 {{ __('Login') }}             </button>         </div>     </div>     {!! no_captcha()->input() !!} </form> {!! no_captcha()->script() !!} {!! no_captcha()->getApiScript() !!} <script>     grecaptcha.ready(function() {         window.noCaptcha.render('login', function (token) {             document.querySelector('#g-recaptcha-response').value = token;         });     }); </script>  | 
					
Validation
チェック用のtokenがrequestのg-recaptcha-responseでやってきます。
それをValidateするために、ルールを記述します。
例えば、こんな感じ。
| 
					 1 2 3 4 5 6 7  | 
						        $request->validate([             // 中略             'g-recaptcha-response' => ['required', new \Arcanedev\NoCaptcha\Rules\CaptchaRule]         ], [             'g-recaptcha-response.required' => 'v2のチェックボックスなら、チェックがされていないときのメッセージ',             'g-recaptcha-response.captcha'  => 'ロボットだと判断されてしまった時のメッセージ',         ]);  | 
					
ここまでやれば、おしまい。
後は実行するのみです。
最後に
意外と簡単に終わります。
使っている人が多いフレームワークは、いろんな情報が転がってて助かります。
r.tanakaがお届けしました。
