昨日今日と妻が子供たちとママ友の所にお泊まりに行っているので、若干風邪気味なのも相まって自宅に引き篭もってプログラミングを行っていた。 いずれ必要になるので Blog にコメント機能を付加していた。

コメント機能を追加するにはスパム対策が必須

自前の Blog にコメント機能を追加する場合に考慮しなければならない最重要の問題はスパム対策だ。 何も対策をしない場合、手塩にかけて作った Blog が奇妙な URL やメールアドレス、英語などに汚染されたコメントで荒らされてしまう。

日本人のみ投稿できればいいのであれば、投稿する際に日本人しか回答不能な質問を付加して答えさせるのが有効だ。 例えば「十三たす四=」などといった感じだ。この場合 17 が飛んでくればコメントの投稿を許すこととなる。 まぁこれでもいいのだが、折角 Google が提供している画像認証用のライブラリを見つけたのでそれを使ってみた。 reCAPTCHA という。

reCAPTCHA で認証後に Ajax で送る場合

この記事の右下に「コメント投稿」というボタンがあると思うのでそれを押してみてほしい (ただボタンを押しただけではコメントは投稿されないので安心して欲しい)。 そうするとダイアログが開くが、画面左下に「私はロボットではありません」などというチェックボックスが表示される。 これをチェックすると時にはそのままで「人間であることの証明」が終わり、時には追加の証明手段として画像認証が表示される。 どういうロジックになっているのか分からないがすごい。

これの実装の仕方はこの解説サイトがものすごく分かり易かったので興味があればそちらを参照して頂きたい。 あと reCAPTCHA 公式を見るのもいい。

要するに JavaScript のライブラリを読み込んで指定された HTML タグを書くとそこに認証用のビューが表示される。 そこで認証を行うとフォームに g-recaptcha-response という ID, クラスの HTML 要素に認証済を示すトークンが埋め込まれるので、それをそのまま POST するなり Ajax で送るなりすれば良い。そんなに難しくはなかった。つまり jQuery だと以下で認証済トークンが取れる:

var gRecaptchaResponse = $('#g-recaptcha-response').val();

注意点として、この認証済トークンを POST (Ajax) した先でこのトークンが有効なものかの検査 (https://www.google.com/recaptcha/api/siteverify?secret={Secret key}&response={認証コード} に対し GET リクエストを送り戻りの JSON を見る) を行うが、 この g-recaptcha-response は使い捨てなので 1 回チェックを行ってしまうと次からは不正を示す {success: false} が返却されてしまう。 なのでこの検査はバリデーションチェック等がすべて終わりこれさえ通れば正常終了という箇所で行うのが良い。