Previnindo SPAM em formulários Rails utilizando invisible captcha

SPAM

Qualquer aplicação web com formulários que não exigem autenticação do usuário, sofre do mesmo problema: o SPAM! Em sua maioria, preenchido por spambots.

A técnica mais utilizada para a prevenção é o uso do reCAPTCHA, oficialmente originado do CAPTCHA, que foi desenvolvido pioneiramente na universidade de Carnegie-Mellon, nos EUA.

Um CAPTCHA usual envolve um computador (um servidor) que pede que um usuário termine um teste. Como os bots são incapazes de resolver o CAPTCHA, todo usuário que incorpora uma solução correta é presumidamente humano.

Já o reCAPTCHA pede para usuários digitarem palavras distorcidas exibidas na tela. Além de proteger que os robôs preencham os formulários, ele ajuda a digitalizar o texto de livros.

O problema é que o reCAPTCHA se torna chato para os usuários, o que atrapalha e muito na UX.

Utilizando a técnica de honeypot

A técnica de Honeypot ou Invisible Captcha consiste no uso de um campo invisível no formulário. Os bots em sua maioria não carregam todo o HTML, CSS e Javascript da página. Isso faz com que eles não tenham uma visão da página como ela realmente é, não conseguindo distinguir os campos visíveis dos invisíveis.

Qual o resultado?

Eles vão preencher o nosso honeypot!

Utilizando a gem Invisible Captcha

A gem invisible_captcha é muito simples, vamos ao passo a passo:

Adicione ao seu Gemfile:

1
gem 'invisible_captcha'

Existe mais de uma forma de implementação, abordaremos aqui a implementação no Modelo.

Baste adicionar um atributo virtual a sua classe, como no exemplo abaixo e setá-lo como ‘invisible_captcha’:

1
2
3
4
class Topic < ActiveRecord::Base
  attr_accessor :subtitle # virtual attribute, the honeypot
  validates :subtitle, invisible_captcha: true
end

Se você estiver usando strong_parameters, não se esqueça de colocar o atributo na hash de parâmetros.

1
2
3
def topic_params
  params.require(:topic).permit(:subtitle)
end

Configuração Extra

Para customizar as configurações, adicione o arquivo invisible_captcha.rb em config/initializers com o seguinte:

1
2
3
4
5
InvisibleCaptcha.setup do |ic|
  ic.sentence_for_humans = 'Se você é humano, por favor, ignore este campo.'
  ic.error_message = 'Você é um robô!'
  ic.fake_fields << 'fake_field'
end

Agora basta colocar o formulário na view:

1
2
3
<%= form_for(@topic) do |f| %>
  <%= f.invisible_captcha :subtitle %>
<% end %>

Para ver o funcionamento, vá ao seu formulário com o inspetor do elemento do seu navegador e procure pelo honeypot. Veja um exemplo abaixo:

inspecionando elemento do honeypot