😉
Rails recaptcha v3を導入
はじめにを読んだ
利用を開始するにはAPIキーを登録する必要がある。
開発環境用にドメインにlocal_host必要
クライアントサイドを読んで実装
headタグ
<!-- Google reCAPTCHA -->
<script src="https://www.google.com/recaptcha/api.js?render=<%= Rails.application.credentials[:recaptcha_client] %>"></script>
<script>
document.addEventListener("turbo:load", function() {
grecaptcha.ready(function() {
grecaptcha.execute("<%= Rails.application.credentials[:recaptcha_client] %>", { action: アクション }).then(function(token) {
const recaptchaResponse = document.getElementById('g-recaptcha-response-data');
recaptchaResponse.value = token;
});
});
});
</script>
<!-- // Google reCAPTCHA -->
フォーム内にhiddenフィールドを追加(nameタグがサーバサイドで使われるため注意)
<%= hidden_field_tag '#g-recaptcha-response-data' %>
turboの影響か、grecaptchaが読み取られていません。エラーになる。
サーバーサイドを読んで実装
gem 'recaptcha' を使う場合
※ 認証失敗時モデルにエラーが追加される
@model = Model.new(strong_params)
success = verify_recaptcha(model: @model, minimum_score: 0.9, secret_key: Rails.application.credentials.dig(:recaptcha_backend))
if success && @model.save
flash[:success] = '送信が成功しました。'
redirect_to root_path
else
flash.now[:alert] = '送信が失敗しました'
render :new, status: :unprocessable_entity
end
gem 'recaptcha' を使わない場合
require 'net/https'
require 'json'
uri = URI.parse('https://www.google.com/recaptcha/api/siteverify')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri.path)
req.set_form_data({
'secret' => Rails.application.credentials.dig(:recaptcha_backend),
'response' => params['g-recaptcha-response-data']
})
res = http.request(req)
post_result = JSON.parse(res.body)
if !post_result['success'] || post_result['score'] < 0.9
flash.now[:alert] = 'ロボットではないことを確認できませんでした。'
render :new, status: :unprocessable_entity
return
end
@model = Model.new(strong_params)
if @model.save
flash[:success] = '送信が成功しました。'
redirect_to root_path
else
flash.now[:alert] = '送信が失敗しました'
render :new, status: :unprocessable_entity
end
Discussion