ハローワールド
さて、ウェブサービスやなんかを運営していると、どうしたって一度は迷惑を被ってしまうのがスパムメールです。公開されたメールフォームから毎日、仮想通貨のお誘いや怪しいセールスなんかのラブレターが大量に送られてきます。
この度、筆者が公開した新サービスでもさっそくスパムメールをたくさん頂戴したので、熱いご要望にお応えしてスパム対策をしてみました。
どういう対策をするか
単にスパム対策と言っても、いくつか方法があります。
- 国内IPに制限する
- 日本語必須でバリデーションを追加する
- 自動入力を検出する隠しフィールドを追加する
- CAPTCHAを追加する
簡単なところでは、こんなもんですかね。
1の国内IP制限は、なるべくしたくないですね。でも、お寄せいただいたスパムメールの送信元IPを調べてみると、ドイツ・中国・スウェーデンでしたので、IP制限の効果は絶大だと思われます。完全に国内限定にしているサービスはこれで対応すると良いと思います。
2の日本語必須もなるべくしたくないですね。BBCとかから問い合わせ来るかもしれんし・・・
まあ、来ませんけどね。
3は効果が微妙だけど昔からあるトラディッショナルでオーセンティックな対策。CSSとかで隠したフィールドに入力されていると送信を受け付けないという仕組み。
4は、とても強力ですが、一般ユーザーの利便性が損なわれる上、導入コストが高いです。WordPressだとサクッと実装できちゃうんですけどね・・・
Gemがあるようですが、新し目のRailsはサポートされていないようです
やっていく
というわけで今回は3の隠しフィールドでちゃちゃっと対応してみようと思います。
スパムさんにちゃんと入力してもらえるような素敵な隠しフィールドにしましょうね。
今回のポイント
- hidden_fieldは使わず、通常のtext_fieldを使い、フィールドはCSSで隠す
- 罠フィールドを入力禁止バリデーションを追加する
これでやっていく
ソースコード
対象となるモデルはInquiryです。
まず、viewのテンプレートに罠フィールドを追加します。今回は一応、”本物の”本文の直前に挿入しました。
form.html.erb
<!-- これは罠です-->
<%= form.text_field :message %>
続いてコントローラー。inquiry_controller.rbのストロングパラメーターに罠フィールドを追加。
def inquiry_params
params.require(:inquiry).permit(
## 中略
:message
)
end
次にモデル。
バリデーションを追加。そしてDBには関係ない項目なのでinquiry.rbにattr_accessorを追加します。
validates :message, absence: true #入力されたらエラー
attr_accessor :message
入力フォームをcssで非表示にしときます。
#inquiry_message{
display: none;
}
あとはRailsを再起動して終わりです🎉
さいごに
毎日来ていたスパムメールですが、実装後はまったく来なくなりました。
お手軽すぎるスパム対策なのでやや不安でしたが、今のところ看破された形跡はありません。
この方法なら、善良なユーザーに迷惑をかけることもないので、まずは隠しフィールドから試してみるといいかもですね
おわり🏆