liuzhenangel / concise_rucaptcha

#1
c4cbbd0ca4[1].png

This is a Captcha gem for Rails Applications which generates captcha image by C code.

Example


Feature
  • No dependencies. No ImageMagick. No RMagick;
  • For Rails Application;
  • Simple, Easy to use;
  • High performance.
Usage
Put rucaptcha in your Gemfile:

gem 'concise_rucaptcha'

Create config/initializers/concise_rucaptcha.rb

ConciseRuCaptcha.configure do
# Color style, default: :colorful, allows: [:colorful, :black_white]
# self.style = :colorful
# Custom captcha code expire time if you need, default: 2 minutes
# self.expires_in = 120
# [Requirement]
# Store Captcha code where, this config more like Rails config.cache_store
# default: Read config info from `Rails.application.config.cache_store`
# But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]

self.cache_store = :mem_cache_store


(RuCaptha do not use Rails Session to store captcha information. As the default session is stored in Cookie in Rails, there's a Replay attack bug which may causes capthcha being destroyed if we store captcha in Rails Session.

So in my design I require RuCaptcha to configure a distributed backend storage scheme, such as Memcached, Redis or other cache_store schemes which support distribution.

Meanwhile, for the ease of use, RuCapthca would try to use :file_store by default and store the capthca in tmp/cache/rucaptcha/session directory (kindly note that it's not working if deploy on multiple machine).

For recommendation, configure the cache_store(more details on Rails Guides Configuration of Cache Stores) to Memcached or Redis, that would be the best practice.)

Controller app/controller/account_controller.rb

When you called verify_rucaptcha?, it uses value from params[:_rucaptcha] to validate.

Code:
class AccountController < ApplicationController
  def create
    @user = User.new(params[:user])
    if verify_rucaptcha?(@user) && @user.save
      redirect_to root_path, notice: 'Sign up successed.'
    else
      render 'account/new'
    end
  end
end

class ForgotPasswordController < ApplicationController
  def create
    # without any args
    if verify_rucaptcha?
      to_send_email
    else
      redirect_to '/forgot-password', alert: 'Invalid captcha code.'
    end
  end
end
TIP: Sometimes you may need to keep last verified captcha code in session on verify_rucaptcha? method call, you can use keep_session: true. For example: verify_rucaptcha? @user, keep_session: true.​
View app/views/account/new.html.erb
Code:
<form method="POST">
  ...
  <div class="form-group">
    <%= rucaptcha_input_tag(class: 'form-control', placeholder: 'Input Captcha') %>
    <%= rucaptcha_image_tag(alt: 'Captcha') %>
  </div>
  ...

  <div class="form-group">
    <button type="submit" class="btn btn-primary">Submit</button>
  </div>
</form>
And if you are using Devise, you can read this reference to add validation: RuCaptcha with Devise.

Documentation https://github.com/liuzhenangel/concise_rucaptcha