patorashのブログ

方向性はまだない

RailsアプリにreCAPTCHAを導入した

担当アプリのお問い合わせページが中国からのスパム投稿を行われるようになってしまったので、急遽IP制限を追加して一時的に凌ぐことにしたのですが、完全な対策ではないのでreCAPTCHAを導入することにしました。

reCAPTCHAとは?

reCAPTCHAは、Googleが提供している「人間かロボットか」を判断する仕組みです。最近よく見かけるようになったと思いますが、「私はロボットではありません」というチェックボックスにチェックを入れるだけでいいというやつです。

developers.google.com

人間かロボットかの判断をGoogle側に依存するようになるのですが、まぁ問題ないかと思います。

Railsアプリでの導入について

RailsアプリでのreCAPTCHAの導入は簡単です。recaptchaというgemがあります。

github.com

reCAPTCHAのキーの発行

まずは以下のリンクからGet reCAPTCHAボタンを押して、reCAPTCHAのキーを取得します。

www.google.com

次に、

  1. ラベルにわかりやすいものを設定します。(ドメイン名、何のページか等)
  2. reCAPTCHAのタイプを選択します。今回はreCAPTCHGA v2。
  3. ドメインを設定します。サブドメインも設定することと、開発環境で試す場合はlocalhost127.0.0.1なども登録しておいたほうがいいでしょう。
  4. 利用規約に同意して登録します。

f:id:patorash:20180403163946p:plain

キーが発行されるので、それをRailsアプリに登録していきます。

Railsアプリでの設定

recaptchaのサイトに導入の仕方は書いてありますが、一応書きます。

gem recaptchaのインストール

Gemfileに以下を追加します。

gem 'recaptcha', require: "recaptcha/rails"

そして、bundle installを実行します。

環境変数の設定

環境変数にreCAPTCHAで発行されたキー類を登録しておきます。 開発環境でdotenvを使っている場合は、以下のようにしましょう。

RECAPTCHA_SITE_KEY = '発行されたサイトキーをここに設定'
RECAPTCHA_SECRET_KEY = '発行されたシークレットキーをここに設定'
ViewにreCAPTCHAを表示する

あとは、Viewのformタグの内側にreCAPTCHA用のタグを出力します。人として認証されたらJavaScriptのコールバック関数を呼ぶことができますので、それが成立したら送信ボタンを有効にする、なども可能です。コードはslimで書いていますのであしからず。

= form_for @foo do |f|
  # 他のタグ
  = recaptcha_tags callback: 'successRecaptchaVerified'
  # 他のタグ
Controller側でreCAPTCHAのチェック

最後に、Controllerでチェックします。

def create
  @foo = Foo.new(foo_params)
  if verify_recaptcha(model: @foo) && @foo.save
    redirect_to @foo
  else
    render 'new'
  end
end

これで完了です。が、みなさんテストを書いていますよね?その場合は追加が必要です。

テストでreCAPTCHAの認証をパスする

gem recaptchaはテストの際はverify_recaptchaの結果を常にtrueを返すようになっていますので、引数に環境を渡す必要があります。env: Rails.envを追加してください。

def create
  @foo = Foo.new(foo_params)
  if verify_recaptcha(model: @foo, env: Rails.env) && @foo.save
    redirect_to @foo
  else
    render 'new'
  end
end

これでOKです。

まとめ

reCAPTCHAの導入は比較的簡単で助かりました。ただ、ローカルで何度も実験しようとすると、すぐにロボット扱いされてしまって困りました。ブラウザを変えるなどして凌いだのですが、いい方法はないものか…。どなたかご存知であれば教えてください。