RobotCatcher makes your forms smarter and keeps bots away.
Prerequisites:
- Ruby 1.9.3 or above (built with for example rbenv and ruby-build)
- Bundle
- A Rails application (Rails 3.2.22)
Installation is simple! Add this line to your application's Gemfile:
gem 'robot_catcher'
Or in your gem specification (gemspec) file:
Gem::Specification.new do |s|
...
s.add_dependency 'robot_catcher'
After running bundle install
, RobotCatcher's functionality will be available in your
project.
NB: Remember to require 'robot_catcher
manually in case RobotCatcher is a
depedency of your engine, or require
it in the library file of your engine.
RobotCatcher is a small form plugin that uses several kinds of hashing to consider whether a form has been filled out by a bot or a human being.
In any forms in your Rails application. Instead of form_for
, use rc_form_for
,
and specify the request ip address as an argument (typically request.remote_ip
:
rc_form_for(@article, ip: request.remote_ip) do |f|
f.label 'title'
f.text_field 'title'
f.label 'text'
f.text_area 'text'
f.submit
end
Idem dito in case you want to use form_tag
or anyother field *_tag
:
rc_form_tag('/articles', ip: request.remote_ip) do
label_tag 'title'
rc_text_field_tag 'title'
label_tag 'text'
rc_text_area_tag 'text'
submit_tag
end
NB: In case of tags, only use tags helper methods on fields (i.e. not on labels or submit).
In special cases, especially when mixing html and erb, you might want to
generate a hash input manually. Important: the label in rc_hash_tag
should
correspond to the name
attribute's value in the following input tag:
<%= rc_form_tag('/articles', ip: request.remote_ip) do %>
<label for="title">Title</label>
<%= rc_hash_tag 'title' %>
<input id="title" type="text" name="title"></input>
...
<% end %>
To specify the attributes that should be investigated by the robot catcher,
use the class method robot_catch
. See the example below. A prerequisite
is that the model class is a child of ActiveRecord::Base.
class Article < ActiveRecord::Base
robot_catch :title, :text
...
end
In the current version, catching robots is done by using the robot?
method on
a model object. The arguments are the original params hash
(technically a ActionController::Parameters instance), and the request ip address.
It be the original params hash because that hash contains the information (i.e.
spinner, timestamp, etc.) that the robot catcher checks. See the example below.
def create
@article = Article.new(params[:article])
if @article.robot?(params, request.remote_ip)
redirect_to @article, notice: 'Stupid robot.'
return
end
if @article.save
redirect_to @article, notice: 'Article was successfully created.'
else
render :new
end
end
NB: This requires some knowledge about the difference between what rc_form_for
and rc_form_tag
generates. As for in the example given in the front-end section
with rc_form_tag
, the params hash will include no :article
key, so a new
article object is made by passing in the raw params
hash (since this contains
the right attribute keys and values). Anyway, if you want to do it the Rails way,
use rc_form_for
like in the example above.
- Store robot catches in database
- Configuration (e.g. for a secret that is used for hashing)
- Better usage of concerns
- More DRY
- Random order on spinner hasher
- Support for more tags
- Integration into native validations
- Rewriting native form helper class
This project uses MIT-LICENSE.