Recaptchaの代替案として laravel-honeypot を使ってみる

さてさて、この間公開した記事 Laravel + Vue + axios でreCAPTCHAバージョン3を実装する では、Google が提供するスパム対策サービスRecaptchaLaravelで使う方法をご紹介しました。

個人的な印象では、このRecaptchaを使えば今の所完璧にスパム送信をブロックできているようで、さすがはGoogleさんといったところです。

ただ、Recaptchaはとても便利ですが、いろいろと複雑な設定をしないといけないので「うーん、そこまで完璧じゃなくていいからもっと簡単にできないかな・・・」と感じる方も多いかもしれません。

そこで!

今回紹介するのが laravel-honeypot というパッケージです。

このパッケージは無差別にデータ送信してくるプログラムの逆手をとってスパム対策をするというものなのですが、これは結構有効だと思うので完璧を求めなくてもいい場合は選択肢として検討してもいいかなと感じています。

ぜひ皆さんのお役に立てると嬉しいです😊✨

開発環境: Laravel 6.x

laravel-honeypotが使っている作戦は?

知ってのとおりスパムをするプログラムは、「とにかく入力ボックスがあったらテキストを入力してすればメール送信してくれるだろう」という作戦で無差別にアクセスをしてきます。

laravel-honeypotは、この作戦を逆手にとります。

つまり、全く使わない入力ボックスを用意しておいて、もしその内容が変わっていればスパムと判断するという作戦です。(ちなみに、この「全く使わない入力ボックス」のことをhoneypotと呼ぶそうです)

これって逆転の発想でとってもスマートですよね。
では、実際の使い方をご紹介しましょう!

インストールする

laravel-honeypotは、composer一発でインストールができます。

以下のコマンドを実行してください。

composer require spatie/laravel-honeypot

ルートに専用のミドルウェアをセットする

Recaptchaの場合は、バリデーションで処理をしましたがlaravel-honeyはミドルウェアとして使います。

そのため、laravel-honeypotを使う場合はroutes/web.phpの中で以下のようにします。

// フォーム
Route::get('honeypot', 'HoneypotController@create');
// 送信先
Route::post('honeypot', 'HoneypotController@store')->middleware(\Spatie\Honeypot\ProtectAgainstSpam::class);

送信フォームの設定

送信先にミドルウェアを設定したら、あとは送信側のフォームに@honeypotというBladeディレクティブを追加するだけで完了です。

<html>
<body>
    <form method="POST">
        @honeypot
        @csrf
        <input name="subject" type="text">
        <br>
        <button type="submit">送信する</button>
    </form>
</body>
</html>

@honeypotを追加すると以下のようなコードが追加されることになります。

<div id="my_name_PVHiCaSb1HtotKNe_wrap" style="display:none;">
    <input name="my_name_PVHiCaSb1HtotKNe" type="text" value="" id="my_name_PVHiCaSb1HtotKNe">
    <input name="valid_from" type="text" value="eyJpdiI6Ikg2STRGU1wvdHdOXC9JZHNwRjRlQkZhZz09IiwidmFsdWUiOiJ5TVBFZ21wUXM4Wk50a1B4VlVcL3dRUT09IiwibWFjIjoiMWU1ZjNlNWJlZTNkMjVjMzRhNzEyMDY3Mjc3N2U3M2NhNTllMDJhMjIyNjRkYzJkN2QwMzMzZWFkZjkzOWY5NSJ9">
</div>

ただし、このコード部分はブラウザ上では表示されることはありません。(CSSで消されています)

一番シンプルに使う場合はここまでで完了です。
お疲れ様でした😊✨

もしスパム送信されたらどうなるのか

デフォルトでは、ブランクページが表示されることになります。(HTTPステータスは200が返ります)

もし、このページをカスタマイズしたい場合はコンフィグ設定respond_to_spam_withをを参考にしてみてください。

コンフィグ設定

laravel-honeypotは、コンフィグ・ファイルで各種設定をお好みに変更できます。

まずは以下のコマンドでファイルをconfigフォルダにコピーしましょう。

php artisan vendor:publish --provider="Spatie\Honeypot\HoneypotServiceProvider" --tag=config

コマンド実行すると、config/honeypot.phpというファイルが作成されるのでこのファイルの中身を変更します。

name_field_name

初期値ではmy_nameというキーが基準としてコンテンツが作成されますが、この値を変更することができます。

例えば、titleに変更すると以下のようになります。

<div id="title_l0O4boBxSw1ibGdK_wrap" style="display:none;">
    <input name="title_l0O4boBxSw1ibGdK" type="text" value="" id="title_l0O4boBxSw1ibGdK">
    <input name="valid_from" type="text" value="eyJpdiI6ImxJekdWNzhpUWsyV29YRVFCdmhndUE9PSIsInZhbHVlIjoiVVNBMnBTVDdMUWJPYkszTVhQbEFUZz09IiwibWFjIjoiM2I0OGNkZDM3ZDEyZGMzNTgzMTE0OWQwZjkxNzI2YjQ5NTE4MmNmZGVmNzBkMWU0MTNjYWFmNGFjY2U0NzQ4MCJ9">
</div>

randomize_name_field_name

初期状態ではname_field_nameにはランダムな文字列がつけられるのですが、ここをfalseにすると、そのランダムな文字列が作成されなくなります。

<div id="title_wrap" style="display:none;">
    <input name="title" type="text" value="" id="title">

つまり、毎回honeypot入力の名前は同じになります。

valid_from_field_name

フォーム名を送信する<input>nameを変更する設定です。

実際に変更するとこのようになります。

<input name="contact_form" type="text" value="*****">

amount_of_seconds

スパムのプログラムは無差別に入力して送信するため、ページを開いてから送信するまでの時間が短いことが多いです。そのため、ここで設定されている秒数よりも少ない時間で送信されたものはスパムとして処理できるようになります。

'amount_of_seconds' => env('HONEYPOT_SECONDS', 3), // 3秒以内に送信されたらスパム認定

respond_to_spam_with

スパムが発生した場合に表示する内容をクラスで指定します。

例えば、app/Http/Honeypot/CustomSpamResponder.phpにカスタマイズしたクラスを以下のようにつくって設定してみます。

<?php

namespace App\Http\Honeypot;

use Closure;
use Illuminate\Http\Request;
use Spatie\Honeypot\SpamResponder\SpamResponder;

class CustomSpamResponder implements SpamResponder
{
    public function respond(Request $request, Closure $next)
    {
        return response('スパム、ダメ絶対!');
    }
}

コンフィグは以下のようにします。

'respond_to_spam_with' => \App\Http\Honeypot\CustomSpamResponder::class,

そして、実際にスパム判別されたら以下のようになります。

enabled

laravel-honeypotの有効/無効を変更します。本番環境と開発環境で使い分けるといいかもしれません。

おわりに

ということで、今回は手軽にスパム対策ができるパッケージlaravel-honeypotを紹介しました。

この記事を書いている時点(2019.11.14現在)でGitHubのスターが350を超えているので人気パッケージであることは間違いないでしょうし、MITライセンスで公開されているので、商用の開発であっても使いやすいんじゃないでしょうか。

ぜひ皆さんの開発にも使ってみてくださいね。

ではでは〜!

この記事が役立ちましたらシェアお願いします😊✨