rucaptcha/README.md

5.4 KiB

RuCaptcha

Gem Version Build Status Code Climate

This is a Captcha gem for Rails Applications. It drawing captcha image with 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 'rucaptcha'

Create config/initializers/rucaptcha.rb

RuCaptcha.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]
  # 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,并尝试用可以运行的方式,用于存储验证码字符
  # 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
  self.cache_store = :mem_cache_store
end

Controller app/controller/account_controller.rb

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

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: Sometime you may need 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

<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 use Devise, you can read this to add validation: RuCaptcha with Devise.

Write your test skip captcha validation

for RSpec

describe 'sign up and login', type: :feature do
  before do
    allow_any_instance_of(ActionController::Base).to receive(:verify_rucaptcha?).and_return(true)
  end

  it { ... }
end

for MiniTest

class ActionDispatch::IntegrationTest
  def sign_in(user)
    ActionController::Base.any_instance.stubs(:verify_rucaptcha?).returns(true)
    post user_session_path \
         'user[email]'    => user.email,
         'user[password]' => user.password
  end
end

Invalid message without Devise

When you are using this gem without Devise, you may find out that the invalid message is missing. For this case, use the trick below to manually add your i18n invalid message.

if verify_rucaptcha?(@user) && @user.save
  do_whatever_you_want
  redirect_to someplace_you_want
else
  # this is the trick
  @user.errors.add(:base, t('rucaptcha.invalid'))
  render :new
end