Giter Site home page Giter Site logo

huacnlee / rucaptcha Goto Github PK

View Code? Open in Web Editor NEW
690.0 18.0 133.0 367 KB

Captcha Gem for Rails, which generates captcha image by Rust.

Home Page: https://huacnlee.github.io/rucaptcha

License: MIT License

Ruby 64.11% Makefile 0.55% Rust 35.34%
captcha recaptcha rust magnus ffi

rucaptcha's Introduction

RuCaptcha

Gem Version build

Captcha Gem for Rails, which generates captcha image by Rust.

NOTE: According to the use of Ruby China, the verification code looks like has a lower than 5% probability of being parsed by OCR and the verification code is cracked (All Image Captcha libs are has same problem). It is recommended that you use the IP rate limit to enhance the protection. NOTE: 以 Ruby China 的使用来看,验证码似乎有低于 5% 的概率被 OCR 读取解析 (图片验证码都有这个问题) 导致验证码被破解(我们从日志分析绝大多数是成功的,但偶尔一个成功,配合大量机器攻击,导致注册了很多的垃圾账号),建议你额外配合 IP 频率限制的功能来加强保护。

如果你需要更高强度的验证,建议选择商用服务。

中文介绍和使用说明

Example

0 1 2 3 4 5 6 7 8 9

Feature

  • Native Gem base on Rust.
  • 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
  # 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

  # If you wants disable `cache_store` check warning, you can do it, default: false
  # 如果想要 disable cache_store 的 warning,就设置为 true,default false
  # self.skip_cache_store_check = true

  # Chars length, default: 5, allows: [3 - 7]
  # self.length = 5

  # Enable or disable Strikethrough, default: true
  # self.line = true

  # Enable or disable noise, default: false
  # self.noise = false

  # Set the image format, default: png, allows: [jpeg, png, webp]
  # self.format = 'png'

  # Custom mount path, default: '/rucaptcha'
  # self.mount_path = '/rucaptcha'
end

RuCaptcha 没有使用 Rails Session 来存储验证码信息,因为 Rails 的默认 Session 是存储在 Cookie 里面,如果验证码存在里面会存在 Replay attack 漏洞,导致验证码关卡被攻破。

所以我在设计上要求 RuCaptcha 得配置一个可以支持分布式的后端存储方案例如:Memcached 或 Redis 以及其他可以支持分布式的 cache_store 方案。

同时,为了保障易用性,默认会尝试使用 :file_store 的方式,将验证码存在应用程序的 tmp/cache/rucaptcha/session 目录(但请注意,多机器部署这样是无法正常运作的)。

所以,我建议大家使用的时候,配置上 cache_store (详见 Rails Guides 缓存配置部分的文档)到一个 Memcached 或 Redis,这才是最佳实践。

(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.

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

<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.

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 add your i18n invalid message manually.

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

Performance

rake benchmark to run benchmark test.

Warming up --------------------------------------
      Generate image    51.000  i/100ms
Calculating -------------------------------------
      Generate image    526.350  (± 2.5%) i/s -      2.652k in   5.041681s

rucaptcha's People

Contributors

abookyun avatar anvyzhang avatar chechaoyang avatar dependabot[bot] avatar earlyzhao avatar eric-guo avatar flypiggy avatar gao-jun avatar haibinyu avatar hiveer avatar huacnlee avatar iamphill avatar kamionayuki avatar koali-fang avatar leiz-me avatar liuzhenangel avatar lzyfn123 avatar netqyq avatar ramirovarandas avatar renny-ren avatar renyijiu avatar sonic182 avatar srghma avatar tagliala avatar wanzysky avatar wayne5540 avatar zpvip avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rucaptcha's Issues

vulnerability -> every next fresh session -> same initial captcha

Hello @huacnlee.
I noticed a bug that was produced with the following version:

rucaptcha (2.5.3)
  railties (>= 3.2)

After I've integrated rucaptcha for login form, every next visit with fresh browser history/cache the first generated captcha keeps being the same.

After researching the forks of your gem, I noticed that this bug is not reproduced with the following version:

GIT
  remote: https://github.com/insales/rucaptcha.git
  revision: 3fe084ee93b552393c961ec90cf08b10985048c5
  specs:
    rucaptcha (2.1.3)
      railties (>= 3.2)

Please consider pulling changes and let me know if you need assistance. The mentioned fork's master branch is

insales:master branch is 19 commits ahead, 38 commits behind huacnlee:master.
I can fork insales:master to rebase it on your huacnlee:master branch to create a pull request in case you are willing to merge but too busy to do this.

Please also let me know if the mentioned vulnerability is a result of gem misuse/misconfiguration.

How to print the rucaptcha code?

I konw that in the form, I can use the method verify_rucaptcha? to verify the code, is there any way that I can print or get the rucaptcha code in the back-end?

我在这个gem的基础上做了修改,需要合入吗

我引入这个gem后,用的人都反馈验证码看不太清,每次要输入四五次才能成功,所以我把这个验证码改成了 4 位,没有横线,看起来清晰很多。
image
我想合到你这边,不知道需不需要?

rails 6.0.2.1 RuntimeError

rails 6.0.2是正常的,更新到6.0.2.1后报错如下

Started GET "/rucaptcha/" for 127.0.0.1 at 2019-12-19 21:42:42 +0800
Processing by RuCaptcha::CaptchaController#index as HTML
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms | Allocations: 720)

RuntimeError ():

rack (2.0.8) lib/rack/session/abstract/id.rb:31:in to_s' rucaptcha (2.5.1) lib/rucaptcha/controller_helpers.rb:13:in join'
rucaptcha (2.5.1) lib/rucaptcha/controller_helpers.rb:13:in rucaptcha_sesion_key_key' rucaptcha (2.5.1) lib/rucaptcha/controller_helpers.rb:23:in generate_rucaptcha'
rucaptcha (2.5.1) app/controllers/ru_captcha/captcha_controller.rb:7:in index' actionpack (6.0.2.1) lib/action_controller/metal/basic_implicit_render.rb:6:in send_action'
actionpack (6.0.2.1) lib/abstract_controller/base.rb:196:in process_action' actionpack (6.0.2.1) lib/action_controller/metal/rendering.rb:30:in process_action'
actionpack (6.0.2.1) lib/abstract_controller/callbacks.rb:42:in block in process_action' activesupport (6.0.2.1) lib/active_support/callbacks.rb:135:in run_callbacks'
actionpack (6.0.2.1) lib/abstract_controller/callbacks.rb:41:in process_action' actionpack (6.0.2.1) lib/action_controller/metal/rescue.rb:22:in process_action'
actionpack (6.0.2.1) lib/action_controller/metal/instrumentation.rb:33:in block in process_action' activesupport (6.0.2.1) lib/active_support/notifications.rb:180:in block in instrument'
activesupport (6.0.2.1) lib/active_support/notifications/instrumenter.rb:24:in instrument' activesupport (6.0.2.1) lib/active_support/notifications.rb:180:in instrument'
actionpack (6.0.2.1) lib/action_controller/metal/instrumentation.rb:32:in process_action' actionpack (6.0.2.1) lib/action_controller/metal/params_wrapper.rb:245:in process_action'
activerecord (6.0.2.1) lib/active_record/railties/controller_runtime.rb:27:in process_action' actionpack (6.0.2.1) lib/abstract_controller/base.rb:136:in process'
actionview (6.0.2.1) lib/action_view/rendering.rb:39:in process' actionpack (6.0.2.1) lib/action_controller/metal.rb:191:in dispatch'
actionpack (6.0.2.1) lib/action_controller/metal.rb:252:in dispatch' actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:51:in dispatch'
actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:33:in serve' actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:49:in block in serve'
actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:32:in each' actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:32:in serve'
actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:837:in call' railties (6.0.2.1) lib/rails/engine.rb:526:in call'
railties (6.0.2.1) lib/rails/railtie.rb:190:in public_send' railties (6.0.2.1) lib/rails/railtie.rb:190:in method_missing'
actionpack (6.0.2.1) lib/action_dispatch/routing/mapper.rb:19:in block in <class:Constraints>' actionpack (6.0.2.1) lib/action_dispatch/routing/mapper.rb:48:in serve'
actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:49:in block in serve' actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:32:in each'
actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:32:in serve' actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:837:in call'
rack-attack (6.2.2) lib/rack/attack.rb:170:in call' rack-cors (1.1.0) lib/rack/cors.rb:100:in call'
rack (2.0.8) lib/rack/tempfile_reaper.rb:15:in call' rack (2.0.8) lib/rack/etag.rb:25:in call'
rack (2.0.8) lib/rack/conditional_get.rb:25:in call' rack (2.0.8) lib/rack/head.rb:12:in call'
actionpack (6.0.2.1) lib/action_dispatch/http/content_security_policy.rb:18:in call' rack (2.0.8) lib/rack/session/abstract/id.rb:259:in context'
rack (2.0.8) lib/rack/session/abstract/id.rb:253:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/cookies.rb:648:in call'
activerecord (6.0.2.1) lib/active_record/migration.rb:567:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/callbacks.rb:27:in block in call'
activesupport (6.0.2.1) lib/active_support/callbacks.rb:101:in run_callbacks' actionpack (6.0.2.1) lib/action_dispatch/middleware/callbacks.rb:26:in call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:32:in call' web-console (4.0.1) lib/web_console/middleware.rb:132:in call_app'
web-console (4.0.1) lib/web_console/middleware.rb:28:in block in call' web-console (4.0.1) lib/web_console/middleware.rb:17:in catch'
web-console (4.0.1) lib/web_console/middleware.rb:17:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in call'
railties (6.0.2.1) lib/rails/rack/logger.rb:38:in call_app' railties (6.0.2.1) lib/rails/rack/logger.rb:26:in block in call'
activesupport (6.0.2.1) lib/active_support/tagged_logging.rb:80:in block in tagged' activesupport (6.0.2.1) lib/active_support/tagged_logging.rb:28:in tagged'
activesupport (6.0.2.1) lib/active_support/tagged_logging.rb:80:in tagged' railties (6.0.2.1) lib/rails/rack/logger.rb:26:in call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/remote_ip.rb:81:in call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/request_id.rb:27:in call' rack (2.0.8) lib/rack/method_override.rb:22:in call'
rack (2.0.8) lib/rack/runtime.rb:22:in call' activesupport (6.0.2.1) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/static.rb:126:in call'
rack (2.0.8) lib/rack/sendfile.rb:111:in call' actionpack (6.0.2.1) lib/action_dispatch/middleware/host_authorization.rb:83:in call'
webpacker (4.2.2) lib/webpacker/dev_server_proxy.rb:23:in perform_request' rack-proxy (0.6.5) lib/rack/proxy.rb:57:in call'
railties (6.0.2.1) lib/rails/engine.rb:526:in call' puma (4.3.1) lib/puma/configuration.rb:228:in call'
puma (4.3.1) lib/puma/server.rb:681:in handle_request' puma (4.3.1) lib/puma/server.rb:472:in process_client'
puma (4.3.1) lib/puma/server.rb:328:in block in run' puma (4.3.1) lib/puma/thread_pool.rb:134:in block in spawn_thread'

Can't reload Captcha in Firefox with AJAX

Link: https://www.fineprintnyc.com/estimate

When I press on the refresh image link, it loads the snippet of HTML correctly.

Except in Firefox, the HTML is updated but the same CAPTCHA image is showing

$(document).on 'click touchstart', '.refresh-captcha', (e)->
      $.ajax
        url: '/captcha'
        method: 'get'
        cache: false
        dataType: "html"
        success: (data)->
          $('#captcha').html data

convert: unable to read font

在Docker上部署,使用Rails:4.2.4 Image,出现如下错误:

I, [2016-09-25T07:50:07.888809 #1]  INFO -- : Processing by RuCaptcha::CaptchaController#index as HTML
E, [2016-09-25T07:50:07.943286 #1] ERROR -- :   RuCaptcha   RuCaptcha convert: unable to read font `(null)' @ error/annotate.c/RenderFreetype/1127.
convert: unable to read font `(null)' @ error/annotate.c/RenderFreetype/1127.
convert: no images defined `png:-' @ error/convert.c/ConvertImageCommand/3210.

使用devise,当verify_rucaptcha? 后不跟resource参数时,resource.errors里还是出现error

你好:
我使用了devise,不想将验证码失败的error放在user里,想将注册时字段错误信息和验证码失败信息分开,所以想调用verify_rucaptcha? nil,如下例子:

class Users::RegistrationsController < Devise::RegistrationsController

  def create
    build_resource(sign_up_params)
    if verify_rucaptcha?
      resource.save
      yield resource if block_given?
      if resource.persisted?
        if resource.active_for_authentication?
          set_flash_message! :notice, :signed_up
          sign_up(resource_name, resource)
          respond_with resource, location: after_sign_up_path_for(resource)
        else
          set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
          expire_data_after_sign_in!
          respond_with resource, location: after_inactive_sign_up_path_for(resource)
        end
      else
        clean_up_passwords resource
        set_minimum_password_length
        respond_with resource
      end
    else
      #resource.errors.clear
      flash.now[:alert] = t('rucaptcha.invalid')
      clean_up_passwords resource
      respond_with resource
    end
  end
end

2019-04-04 22-18-07屏幕截图

随后看了一下代码,应该是rucaptcha-2.5.0/lib/rucaptcha/controller_helpers.rb里的75行
add_rucaptcha_validation_error方法里resource引用的是全局resource,不是verify_rucaptcha?传进去的resource。

更新2.0.0后默认显示没有安装dalli

全部按照官方的配置进行,但是在启动的时候后台报没有安装dalli。

日志如下:

Started GET "/rucaptcha/" for 127.0.0.1 at 2017-01-25 22:51:50 +0800
Processing by RuCaptcha::CaptchaController#index as HTML
You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install
Completed 500 Internal Server Error in 82ms (ActiveRecord: 0.0ms)

RuntimeError (Could not find cache store adapter for mem_cache_store (cannot load such file -- dalli)):

activesupport (5.0.0) lib/active_support/cache.rb:106:in rescue in retrieve_store_class' activesupport (5.0.0) lib/active_support/cache.rb:104:in retrieve_store_class'
activesupport (5.0.0) lib/active_support/cache.rb:60:in lookup_store' rucaptcha (2.0.0) lib/rucaptcha/cache.rb:7:in cache'
rucaptcha (2.0.0) lib/rucaptcha/controller_helpers.rb:22:in generate_rucaptcha' rucaptcha (2.0.0) app/controllers/ru_captcha/captcha_controller.rb:6:in index'
actionpack (5.0.0) lib/action_controller/metal/basic_implicit_render.rb:4:in send_action' actionpack (5.0.0) lib/abstract_controller/base.rb:188:in process_action'

验证码显示报错

Centos7下安装ImageMegick后,引用RuCaptcha,图片显示不出来,报如下错误,是什么原因
RuntimeError (RuCaptcha: convert: no encode delegate for this image format LABEL' @ error/constitute.c/WriteImage/1171.):
app/middleware/request_throttle.rb:59:in block in call' app/middleware/request_throttle.rb:257:in reserve_capacity'
app/middleware/request_throttle.rb:54:in call' app/middleware/request_context_session.rb:25:in call'
app/middleware/sessions_timeout.rb:22:in call' app/middleware/load_account.rb:12:in call'
app/middleware/request_context_generator.rb:49:in call' app/middleware/prevent_non_multipart_parse.rb:32:in call'`

How can I disable cache_store warning on test env?

Keep getting this warning:

  RuCaptcha's cache_store requirements are stored across processes and machines,
  such as :mem_cache_store, :redis_store, or other distributed storage.
  But your current set is file_store, it has changed to :file_store for working.
  NOTE: :file_store is still not a good way, it only works with single server case.

  Please make config file `config/initializers/rucaptcha.rb` to setup `cache_store`.
  More infomation please read GitHub RuCaptcha README file.
  https://github.com/huacnlee/rucaptcha

Invalid message not shown

I am using this gem without devise, version == 2.1.3.

Not sure why but cannot get the invalid message. Just follow the instructions.
Now in order to get an error message, I have to manually add a line of code to make it happen.

    if verify_rucaptcha?(@user) && @user.save
      @user.send_activation_email
      redirect_to activate_user_url(@user)
    else
      # this one below
      @user.errors.add(:base, t('rucaptcha.invalid'))
      render :new
    end

ImageMagic 升级后,图形验证码报错, 最新版的 rucaptcha 也不起作用

RuntimeError (RuCaptcha: convert: not authorized `-' @ error/constitute.c/ReadImage/453.
convert: missing an image filename `png:-' @ error/convert.c/ConvertImageCommand/3015.):
  rucaptcha (0.4.5) lib/rucaptcha/captcha.rb:81:in `create'
  rucaptcha (0.4.5) lib/rucaptcha/cache.rb:18:in `block in create_with_cache'
  activesupport (4.2.5) lib/active_support/cache.rb:299:in `block in fetch'
  activesupport (4.2.5) lib/active_support/cache.rb:585:in `block in save_block_result_to_cache'
  activesupport (4.2.5) lib/active_support/cache.rb:547:in `block in instrument'
  activesupport (4.2.5) lib/active_support/notifications.rb:166:in `instrument'
  activesupport (4.2.5) lib/active_support/cache.rb:547:in `instrument'
  activesupport (4.2.5) lib/active_support/cache.rb:584:in `save_block_result_to_cache'
  activesupport (4.2.5) lib/active_support/cache.rb:299:in `fetch'
  rucaptcha (0.4.5) lib/rucaptcha/cache.rb:17:in `create_with_cache'
  rucaptcha (0.4.5) lib/rucaptcha/controller_helpers.rb:13:in `generate_rucaptcha'
  rucaptcha (0.4.5) app/controllers/ru_captcha/captcha_controller.rb:10:in `index'
  actionpack (4.2.5) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.2.5) lib/abstract_controller/base.rb:198:in `process_action'
  actionpack (4.2.5) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.2.5) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.2.5) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.5) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
  activesupport (4.2.5) lib/active_support/callbacks.rb:505:in `call'
  activesupport (4.2.5) lib/active_support/callbacks.rb:498:in `block (2 levels) in around'
  activesupport (4.2.5) lib/active_support/callbacks.rb:313:in `block (2 levels) in halting'
  marginalia (1.3.0) lib/marginalia.rb:77:in `record_query_comment'
  activesupport (4.2.5) lib/active_support/callbacks.rb:432:in `block in make_lambda'
  activesupport (4.2.5) lib/active_support/callbacks.rb:312:in `block in halting'
  activesupport (4.2.5) lib/active_support/callbacks.rb:497:in `block in around'
  activesupport (4.2.5) lib/active_support/callbacks.rb:505:in `call'
  activesupport (4.2.5) lib/active_support/callbacks.rb:92:in `__run_callbacks__'
  activesupport (4.2.5) lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'
  activesupport (4.2.5) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.5) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.2.5) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.2.5) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
  activesupport (4.2.5) lib/active_support/notifications.rb:164:in `block in instrument'
  activesupport (4.2.5) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.2.5) lib/active_support/notifications.rb:164:in `instrument'
  actionpack (4.2.5) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.2.5) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  activerecord (4.2.5) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.2.5) lib/abstract_controller/base.rb:137:in `process'
  actionview (4.2.5) lib/action_view/rendering.rb:30:in `process'
  actionpack (4.2.5) lib/action_controller/metal.rb:196:in `dispatch'
  actionpack (4.2.5) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.2.5) lib/action_controller/metal.rb:237:in `block in action'
  actionpack (4.2.5) lib/action_dispatch/routing/route_set.rb:76:in `dispatch'
  actionpack (4.2.5) lib/action_dispatch/routing/route_set.rb:45:in `serve'
  actionpack (4.2.5) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.5) lib/action_dispatch/journey/router.rb:30:in `each'
  actionpack (4.2.5) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.5) lib/action_dispatch/routing/route_set.rb:817:in `call'
  railties (4.2.5) lib/rails/engine.rb:518:in `call'
  railties (4.2.5) lib/rails/railtie.rb:194:in `public_send'
  railties (4.2.5) lib/rails/railtie.rb:194:in `method_missing'
  actionpack (4.2.5) lib/action_dispatch/routing/mapper.rb:51:in `serve'
  actionpack (4.2.5) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.5) lib/action_dispatch/journey/router.rb:30:in `each'
  actionpack (4.2.5) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.5) lib/action_dispatch/routing/route_set.rb:817:in `call'
  oneapm_rpm (1.3.6) lib/one_apm/rack/middleware_hooks.rb:13:in `traced_call'
  oneapm_rpm (1.3.6) lib/one_apm/rack/middleware_tracing.rb:65:in `call'
  oneapm_rpm (1.3.6) lib/one_apm/rack/browser_monitoring.rb:19:in `traced_call'
  oneapm_rpm (1.3.6) lib/one_apm/rack/middleware_tracing.rb:65:in `call'
  warden (1.2.6) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.6) lib/warden/manager.rb:34:in `catch'
  warden (1.2.6) lib/warden/manager.rb:34:in `call'
  rack (1.6.4) lib/rack/etag.rb:24:in `call'
  rack (1.6.4) lib/rack/conditionalget.rb:25:in `call'
  rack (1.6.4) lib/rack/head.rb:13:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/flash.rb:260:in `call'
  rack (1.6.4) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.6.4) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/cookies.rb:560:in `call'
  activerecord (4.2.5) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.2.5) lib/active_record/connection_adapters/abstract/connection_pool.rb:653:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.2.5) lib/active_support/callbacks.rb:88:in `__run_callbacks__'
  activesupport (4.2.5) lib/active_support/callbacks.rb:778:in `_run_call_callbacks'
  activesupport (4.2.5) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.5) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
  airbrake (4.0.0) lib/airbrake/rails/middleware.rb:13:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.5) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.4) lib/rack/runtime.rb:18:in `call'
  rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
  airbrake (4.0.0) lib/airbrake/user_informer.rb:16:in `_call'
  airbrake (4.0.0) lib/airbrake/user_informer.rb:12:in `call'
  railties (4.2.5) lib/rails/engine.rb:518:in `call'
  railties (4.2.5) lib/rails/application.rb:165:in `call'
  oneapm_rpm (1.3.6) lib/one_apm/rack/middleware_tracing.rb:65:in `call'
  puma (2.9.0) lib/puma/configuration.rb:71:in `call'
  puma (2.9.0) lib/puma/server.rb:490:in `handle_request'
  puma (2.9.0) lib/puma/server.rb:361:in `process_client'
  puma (2.9.0) lib/puma/server.rb:254:in `block in run'
  puma (2.9.0) lib/puma/thread_pool.rb:92:in `block in spawn_thread'

imagemagick 的 convert 命令的版本:

Version: ImageMagick 6.7.2-7 2016-05-09 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP

配置问题

在initializers/rucaptcha.rb文件中配置length和strikethrough无效。

Invalid route name, already in use: 'ru_captcha' (ArgumentError)

部署使用生产环境,启动报错。在本地测试环境使用正常。不知是哪里有问题

routes.rb

  # rucaptcha
  mount RuCaptcha::Engine => "/rucaptcha"
Exiting
/usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/route_set.rb:507:in `add_route': Invalid route name, already in use: 'ru_captcha'  (ArgumentError)
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here:
http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:1657:in `add_route'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:1628:in `decomposed_match'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:1927:in `block in map_match'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:1910:in `each'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:1910:in `map_match'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:1599:in `match'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/mapper.rb:617:in `mount'
	from /data/ruby-apps/siziwang_travel/config/routes.rb:28:in `block in <top (required)>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/route_set.rb:389:in `instance_exec'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/route_set.rb:389:in `eval_block'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/actionpack-5.0.2/lib/action_dispatch/routing/route_set.rb:371:in `draw'
	from /data/ruby-apps/siziwang_travel/config/routes.rb:1:in `<top (required)>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `block in load'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:259:in `load_dependency'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:40:in `block in load_paths'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:40:in `each'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:40:in `load_paths'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:16:in `reload!'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:26:in `block in updater'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/activesupport-5.0.2/lib/active_support/file_update_checker.rb:77:in `execute'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:27:in `updater'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/routes_reloader.rb:7:in `execute_if_updated'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application/finisher.rb:119:in `block in <module:Finisher>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/initializable.rb:30:in `instance_exec'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/initializable.rb:30:in `run'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/initializable.rb:55:in `block in run_initializers'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `each'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `call'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
	from /usr/local/rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/initializable.rb:54:in `run_initializers'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/application.rb:352:in `initialize!'
	from /data/ruby-apps/siziwang_travel/config/environment.rb:5:in `<top (required)>'
	from /data/ruby-apps/siziwang_travel/config.ru:3:in `require_relative'
	from /data/ruby-apps/siziwang_travel/config.ru:3:in `block in <main>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/builder.rb:55:in `instance_eval'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/builder.rb:55:in `initialize'
	from /data/ruby-apps/siziwang_travel/config.ru:in `new'
	from /data/ruby-apps/siziwang_travel/config.ru:in `<main>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/builder.rb:49:in `eval'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/builder.rb:49:in `new_from_string'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/builder.rb:40:in `parse_file'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/server.rb:318:in `build_app_and_options_from_config'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/server.rb:218:in `app'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/server.rb:59:in `app'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/rack-2.0.1/lib/rack/server.rb:353:in `wrapped_app'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/server.rb:124:in `log_to_stdout'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/server.rb:77:in `start'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:90:in `block in server'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:85:in `tap'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:85:in `server'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.2/lib/rails/commands.rb:18:in `<top (required)>'
	from /data/ruby-apps/siziwang_travel/bin/rails:9:in `require'
	from /data/ruby-apps/siziwang_travel/bin/rails:9:in `<top (required)>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/lib/spring/client/rails.rb:28:in `load'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/lib/spring/client/rails.rb:28:in `call'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/lib/spring/client/command.rb:7:in `call'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/lib/spring/client.rb:30:in `run'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/bin/spring:49:in `<top (required)>'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/lib/spring/binstub.rb:31:in `load'
	from /usr/local/rvm/gems/ruby-2.3.1/gems/spring-2.0.1/lib/spring/binstub.rb:31:in `<top (required)>'
	from /data/ruby-apps/siziwang_travel/bin/spring:14:in `require'
	from /data/ruby-apps/siziwang_travel/bin/spring:14:in `<top (required)>'
	from bin/rails:3:in `load'
	from bin/rails:3:in `<main>'

希望可提供 redis_store 的配置功能

如果配置了:redis_store,则会通过lookup_store获取一个cache的obj,但获取到的redis_store是默认配置,通常是指向127.0.0.1的,但如果这个redis_store不在::1上呢?

Windows上的rucaptcha image并没有出现

  1. 配置是 self.cache_store = :redis_store

    有关的gem:

    gem 'rucaptcha', '~> 2.1.2'
    gem 'redis-rails'
  1. 报错信息是
Started GET "/rucaptcha/" for 127.0.0.1 at 2017-03-22 14:42:25 +0800
Processing by RuCaptcha::CaptchaController#index as HTML
Sent file GIF89a一堆乱码(0.0ms)
Completed 500 Internal Server Error in 2833ms (ActiveRecord: 1.0ms)

ArgumentError (string contains null byte):
actionpack (5.0.2) lib/action_controller/metal/data_streaming.rb:67:in `file?'
actionpack (5.0.2) lib/action_controller/metal/data_streaming.rb:67:in `send_file'

调试后发现 gems/rucaptcha-2.1.2/app/controllers/ru_captcha/captcha_controller.rb

if Gem.win_platform?
  send_file data, opts
else
  send_data data, opts
end

如果是windows时,使用的send_file,修改为send_data就会正常显示图片了

Cannot use :file_store in local development env.

I know it is reasonable config for you to make :mem_cache or :redis as a default cache way in production due to cross machines issue. However, if you can leave a :file_store option for develop mode, it will be convenient for developers in their local machine. cheers.

RuCaptcha: dyld: Library not loaded

在mac下报如下错误:


RuntimeError at /
RuCaptcha: dyld: Library not loaded: /usr/X11/lib/libfontconfig.1.dylib
  Referenced from: /usr/local/bin/convert
  Reason: image not found

imagemagick和imagemagick已经安装

Mobile Browser Can Not Request With User Session info

First request from mobile browser: Safari or Chrome in iOS
I, [2018-07-12T19:19:15.634746 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] Started GET "/rucaptcha/" for 220.248.44.178 at 2018-07-12 19:19:15 +0800
I, [2018-07-12T19:19:15.637015 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3]
Processing by RuCaptcha::CaptchaController#index as HTML
I, [2018-07-12T19:19:15.638189 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] rucapcha : session_id =
I, [2018-07-12T19:19:15.638253 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] rucapcha : session.id =
I, [2018-07-12T19:19:15.638316 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] rucapcha : session[:session_id] =
I, [2018-07-12T19:19:15.638375 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] rucapcha : rucaptcha_sesion_key_key = rucaptcha-session:
I, [2018-07-12T19:19:15.638649 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] rucapcha : $redis.get(rucaptcha_sesion_key_key) =
I, [2018-07-12T19:19:15.638939 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] rucapcha : RuCaptcha.cache.read(rucaptcha_sesion_key_key) = {:code=>"rqam", :time=>1531394355}
I, [2018-07-12T19:19:15.639384 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] Rendered text template (0.1ms)
I, [2018-07-12T19:19:15.639543 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] Sent data (0.5ms)
I, [2018-07-12T19:19:15.639675 #23750] INFO -- : [8faf25ee-2b3a-4634-b76e-5ba8f0c9a0a3] Completed 200 OK in 3ms (Views: 0.4ms | ActiveRecord: 0.0ms)

Second Request: from Chrome in mac
I, [2018-07-12T19:19:19.428124 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] Started GET "/rucaptcha/" for 220.248.44.178 at 2018-07-12 19:19:19 +0800
I, [2018-07-12T19:19:19.430369 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] Processing by RuCaptcha::CaptchaController#index as HTML
I, [2018-07-12T19:19:19.431884 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] rucapcha : session_id = 0bdfce54b6d1cab465e2abc48cee91d6
I, [2018-07-12T19:19:19.431973 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] rucapcha : session.id = 0bdfce54b6d1cab465e2abc48cee91d6
I, [2018-07-12T19:19:19.432050 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] rucapcha : session[:session_id] = 0bdfce54b6d1cab465e2abc48cee91d6
I, [2018-07-12T19:19:19.432101 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] rucapcha : rucaptcha_sesion_key_key = rucaptcha-session:0bdfce54b6d1cab465e2abc48cee91d6
I, [2018-07-12T19:19:19.432329 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] rucapcha : $redis.get(rucaptcha_sesion_key_key) =
I, [2018-07-12T19:19:19.432692 #23750] INFO -- : [bc11f394-6d5f-4056-9c87-f9efcc12caaf] rucapcha : RuCaptcha.cache.read(rucaptcha_sesion_key_key) = {:code=>"bfdd", :time=>1531394359}

It can cause many users refresh the same rucaptcha_sesion_key_key:
"rucaptcha-session:"

verify_rucaptcha? return false because store_info is nil

验证总是返回false,经过调试,发现 store_info = RuCaptcha.cache.read(rucaptcha_sesion_key_key) 中的store_info一直返回nil

  • 找到之前的旧贴: #33 , 使用redis_rails这个gem,把session存到redis,store_info依然返回空。
  • console中尝试使用RuCaptcha.cache.read方法也能正确读出hash
  • verify_rucaptcha?verify_rucaptcha?(resource) 方式使用也都是返回false

我的环境之前是 ruby2.4.4 和 rails 5.2.2.1,redis和web服务在同一台服务器上。

最近新开了一台服务器(旧服务器关停),并将ruby升级到2.6.3,rails升级到5.2.3,redis使用内网连接(已确定可正常连接),就出现了这个问题。

edge case in src of rucaptcha_image_tag

In development env. rucaptcha_image_tag will render

<img alt="Rucaptcha" class="rucaptcha-image" src="http://127.0.01:3000/rucaptcha/">

The src attribute include host info. It's ok in local machine.

Edge case: in a remote server, just run with development env and bind local address. use Nginx to listen to 80 and forward request.

rails server -b 0.0.0.0 

In this case, the absolute path of Rucaptcha tag with not working.

Whether using the relative path of image would be better?

<img alt="Rucaptcha" class="rucaptcha-image" src="/rucaptcha/">

verify_rucaptcha?

在本地调试,单步跟踪,发现 verify_rucaptcha?(@user) 一直返回false,请问可能是什么原因?

提供一个captcha ID 的接口会不会更好用?

先在captcha 的索引是通过rucaptcha_sesion_key_key 来存在session 里面的。但是如果是无状态的API 接口的话(移动端),就不太好用了。

像这样把captcha 在存储中的key 返回,就可以支持不用cookie 的API了

  def new_generate_rucaptcha
    res = RuCaptcha.generate()
    session_val = {
        code: res[0],
        time: Time.now.to_i
    }
    RuCaptcha.cache.write(rucaptcha_sesion_key_key, session_val, expires_in: RuCaptcha.config.expires_in)
    opts = { disposition: 'inline', type: 'image/gif', filename: rucaptcha_sesion_key_key }
    send_data  res[1], opts
  end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.