Blog jak widać już nie jest aktualizowany. I raczej nie będzie. Wisi sobie ot tak, ze względów historycznych :)

reCaptcha i Ruby on Rails

Krzysztof Rygielski | 2009-11-16 17:59 | Kategorie: Rails

Jakiś czas temu zainteresowałem się mechanizmem captcha i tym, jak zintegrować go ze stroną napisaną w Ruby on Rails. Natknąłem się na reCaptcha.

Projekt reCaptcha sÅ‚uży przede wszystkim sluży przepisywaniu książek do postaci cyfrowej. Mechanizmy OCR nie radzÄ… sobie z niektórymi starymi tekstami. Zatem poszczególne sÅ‚owa muszÄ… być przepisywane przez ludzi. Użytkownikom udostÄ™pniono narzÄ™dzie, którego mogÄ… używać w swoich serwisach jako trudne do odczytania przez boty captcha. JednoczeÅ›nie wpisujÄ…c odczytane z obrazka sÅ‚owa użytkownicy wypeÅ‚niajÄ…cy formularz przyczyniajÄ… siÄ™ do przepisywania książek do komputerów. Dwie pożyteczne rzeczy za jednym zamachem :-)

Istnieje plugin do rails, który pozwala stosować reCaptcha w serwisach tworzonych w tym frameworku. Można zainstalować to jako globalny gem lub jako plugin do pojedyÅ„czej aplikacji. Ja wybraÅ‚em pierwsze rozwiÄ…zanie. Aktualnie projekt zostaÅ‚ przeniesiony z githuba na gemcutter. Aby móc używać gemcuttera, instalujemy go:

# gem install gemcutter

Następnie wywołujemy komendę:

# gem tumble

i od tej pory gemcutter zostaÅ‚ dodany do źródeÅ‚ i jest ustawiony jako gÅ‚ówne repozytorium gemów. Teraz instalujemy plugin:

# gem install recaptcha

Zanim zaczniemy używać reCaptcha, należy zarejestrować się w serwisie i wygenerować klucze publiczny i prywatny. Cała procedura jest opisana po zarejestrowaniu więc pozwolę sobie ją pominąć.

Klucz prywatny i publiczny umieszczamy w pliku config/environment.rb naszej aplikacji:

ENV['RECAPTCHA_PUBLIC_KEY'] = 'klucz_publiczny'
ENV['RECAPTCHA_PRIVATE_KEY'] = 'klucz_prywatny'

Oczywiście aby gem był używany podczas działania dopisujemy też w environment.rb następującą linijkę:

require 'recaptcha/rails'

Teraz możemy zacząć zabawÄ™ :-) W formularzu, w którym chcemy używać reCaptcha wystarczy dopisać w wybranym miejscu wywoÅ‚anie metody recaptcha_tags. Umieszczona bez żadnych argumentów zaÅ‚aduje standardowe reCaptcha, jakie można zobaczyć np. tutaj. OczywiÅ›cie standardowy wyglÄ…d może nie pasować do caÅ‚oÅ›ci ukÅ‚adu graficznego naszej strony. Można wprowadzać drobne modyfikacje np:

recaptcha_tags :display=>{:theme=>'white'}

spowoduje wyÅ›wietlenie motywu w kolorze biaÅ‚ym. Można też podawać tam różne inne opcje opisane w api reCaptcha. Najlepiej kombinować metodÄ… prób i bÅ‚Ä™dów :-)

W przypadku kiedy nasz formularz jest wysyÅ‚any przy użyciu AJAXa, wówczas reCaptcha nie bÄ™dzie zachowywać siÄ™ prawidÅ‚owo. Należy wówczas dodatkowo dopisać argument :ajax=>true

recaptcha_tags :ajax=>true

MaÅ‚a uwaga: W przypadku instalacji z github, najnowszÄ… możliwÄ… wersjÄ… bÄ™dzie 0.2.2. W tej wersji wystÄ™puje bÅ‚Ä…d, który powoduje, że używajÄ…c opcji :ajax nie da siÄ™ korzystać z innych opcji, np. :display. Po prostu nie przyniosÄ… one żadnego efektu. Po zwróceniu siÄ™ do developera pojawiÅ‚a siÄ™ poprawka. Ja zwyczajnie wprowadziÅ‚em tÄ… zmianÄ™ do pliku /usr/lib/ruby/gems/1.8/gems/ambethia-recaptcha-0.2.2/lib/recaptcha/client_helper.rb. Po jej wprowadzeniu plugin dziaÅ‚a już poprawnie.W repozytoriach gemcutter znajduje siÄ™ najnowsza wersja pluginu przemianowana z ambethia-recaptcha na po prostu recaptcha

Skoro mamy już dodane do formularza pole z kodem reCaptcha, należy sprawdzać czy przepisany kod jest poprawny. W tym celu używamy metody verify_recaptcha. W metodzie obsÅ‚ugujÄ…cej formularz która u mnie wyglÄ…da mniej wiÄ™cej tak:

def create
  @comment = Comment.new(params[:comment])
  if @comment.save
    flash[:message] = "Dzięki za komentarz"
    @comment = Comment.new
  end
end

dopisujÄ™ do instrukcji warunkowej wywoÅ‚anie w nastÄ™pujÄ…cy sposób:

if verify_recaptcha(:model=>@comment, :message=>"Przepisz poprawny kod reCaptcha") and @comment.save

W ten sposób sprawdzana jest poprawność kodu i, jeÅ›li nie jest on prawidÅ‚owy, do listy bÅ‚Ä™dów wypisywanych za pomocÄ… error_messages_for zostanie dodane powiadomienie.

Jeszcze jedna rzecz. Jesli chcemy, możemy caÅ‚kowicie zmienić wyglÄ…d reCaptcha. Wystarczy wywoÅ‚ać recaptcha_tags w nastÄ™pujÄ…cy sposób:

recaptcha_tags :display=>{:theme=>'custom'}

Wówczas nie jest generowany żaden kod html, trzeba go napisać samemu stosujÄ…c siÄ™ do wytycznych podanych również tutaj. Najważniejsze aby na stronie znajdowaÅ‚ siÄ™ div (chociaż ja zastosowaÅ‚em element span) o id równym recaptcha_image oraz pole tekstowe do wpisania kodu o id oraz name równym recaptcha_response_field