Google reCAPTCHA v3
導入の流れ
- サイトを登録してサイトキーとシークレットキーを発行する
- フロントエンドでsubmit時にトークンを発行する
- サーバサイドでスコアを評価する
フロントエンドでsubmit時にトークンを発行する
ログインフォームにreCAPTCHAのトークン用のフィールドを追加し、ログイン時にreCAPTCHAのトークンを発行して、ログインパラメータと合わせてサーバ側に送信するようにします。
(以下のサンプルはslimで書かれています)
= form_with url: signup_path, local: true, html: { name: "signupForm" } do |f|
= f.email_field :email, required: true
= f.password_field :password, required: true
= hidden_field_tag :g_recaptcha
a#signupSubmit ログイン
script src="https://www.google.com/recaptcha/api.js?render=reCAPTCHA_site_key"
javascript:
grecaptcha.ready(() => {
let form = document.querySelector("[name=signupForm]");
if (!form) { return; }
form.querySelector("#signupSubmit").addEventListener("click", () => {
grecaptcha.execute("reCAPTCHA_site_key", { action: "login" }).then((token) => {
const recaptchaField = document.querySelector('#g_recaptcha');
recaptchaField.value = token;
form.submit();
});
});
});
サーバサイドでスコアを評価する
以下のmoduleをapp/controllers/concern等に配置し、controllerでincludeして利用します。
module GoogleRecaptcha VERIFY_ENDPOINT = "https://www.google.com/recaptcha/api/siteverify" def recaptcha_valid_token?(token, min_score) result = recaptcha_verify(token) Rails.logger.info result return false if !result["success"] result.fetch("score", 0.0) >= min_score end def recaptcha_verify(token) req = new_verify_request(token) http = Net::HTTP.new(verify_url.host, verify_url.port) http.use_ssl = verify_url.is_a?(URI::HTTPS) res = http.request(req) return { "success" => false } if res.code != "200" JSON.parse(res.body) end def verify_url @verify_url ||= URI.parse(VERIFY_ENDPOINT) end def new_verify_request(token) req = Net::HTTP::Post.new(verify_url) req.set_form_data(verify_parameters(token)) req end def verify_parameters(token) { secret: "reCAPTCHA_secret_key", response: token, } end end
controller側のサンプルコードはこちらです。
class SessionsController < ApplicationController include GoogleRecaptcha # GET /signin def new; end # POST /sessions def create if recaptcha_valid_token?(params[:g_recaptcha], 0.5) # ログイン処理 else # reCAPTCHAのスコアがしきい値より低かった場合の処理 end end end