ryoma's note

マイペース ੯•́ʔ̋ ͙͛*͛ ͙͛*͛ ͙͛̋و

reCAPTCHA v3を試してみる

reCAPTCHA は手軽に導入できるらしいと聞いたので、ローカル環境で試しに動かしてみる。

現在は reCAPTCHA v3 と v2 から選択して利用できる。v3 は利用者またはボットの行動を数値化し、基準値を満たしているかで検証する。v2 は利用者に「私はロボットじゃないよ」のチェックボックス等を操作してもらって検証を行うみたい。

reCAPTCHA v3 verifies requests with a score and gives you the ability to take action in the context of your site.
reCAPTCHA v2 verifies if an interaction is legitimate with the “I am not a robot” checkbox and invisible reCAPTCHA badge challenges.

今回は v3 と v2 の両方を試したいので、それぞれでサイトを登録して API キー(サイトキーとシークレットキー)を発行する。ローカル環境の場合、ドメインには「localhost」を登録する。

Ruby on Rails の Web アプリケーションへの導入を検討しているので、yasslab/sample_apps のサンプルアプリケーションをお借りする。また、ambethia/recaptcha という便利な Gem が公開されていたので使わせてもらう。

README を読んでみると、初回は v3 で検証を行うが、失敗した場合に v2 のチェックボックス等を表示させてフォールバックできる方法が紹介されていた。v3 は便利だが検証の精度が気になっていたので、その通りに実装する。

# .env
RECAPTCHA_SITE_KEY=***
RECAPTCHA_SECRET_KEY=***
RECAPTCHA_SITE_KEY_V3=***
RECAPTCHA_SECRET_KEY_V3=***
# config/initializers/recaptcha.rb
Recaptcha.configure do |config|
  config.site_key = ENV['RECAPTCHA_SITE_KEY']
  config.secret_key = ENV['RECAPTCHA_SECRET_KEY']
end
# app/controllers/sessions_controller.rb
def create
  success = verify_recaptcha(action: 'login', minimum_score: 0.5, secret_key: ENV['RECAPTCHA_SECRET_KEY_V3'])
  checkbox_success = verify_recaptcha unless success
  if success || checkbox_success
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      # ログイン成功
    else
      # ログイン失敗
    end
  else
    if !success
      @show_checkbox_recaptcha = true
    end
    render 'new'
  end
end
# app/views/sessions/new.html.erb
<%= form_with(url: login_path, scope: :session, local: true) do |f| %>
  …
  <% if @show_checkbox_recaptcha %>
    <%= recaptcha_tags %>
  <% else %>
    <%= recaptcha_v3(action: 'login', site_key: ENV['RECAPTCHA_SITE_KEY_V3']) %>
  <% end %>
  <%= f.submit "Log in", class: "btn btn-primary" %>
<% end %>

通常は v3 で検証を行うが、スコアが基準値を下回るなどして検証に失敗すると v2 のチェックボックスが表示されるログインフォームになった。

f:id:ryoma123:20211116000921p:plainf:id:ryoma123:20211116000924p:plain
reCAPTCHA v3 と v2 の表示例

自動判定されるスコアの精度が気になっていたが、この方法であれば v2 で救済できるので気軽に導入を試してみてもよさそうに感じた。実装も Gem のおかげで手軽でした 🙏