Gem RuCaptcha 2.0.0 验证码 Gem 发布,不需要依赖 ImageMagick 啦!

huacnlee · 2017年01月22日 · 最后由 zhangtalent 回复于 2022年04月28日 · 9827 次阅读

早些时候,我发布了 RuCaptcha 用于解决各类项目验证码问题的 Gem。

https://ruby-china.org/topics/27832

其目的是为了解决大家在使用验证码 Gem 的过程中遇到的三方库依赖问题。但使用一段时间以后发现,仍然还有许多人在安装 ImageMagick 的时候遇到各类奇怪的问题(尤其是 CentOS 手动安装的)。

我曾经想过用一个 Go 里面的库来编译成二进制搞到 RuCaptcha 里面调用,这样就完全没有依赖了。但尝试以后发现不行,Go 编译出来的文件过大。

于是我尝试寻找存 C 实现的,终于找到了一个:

http://brokestream.com/captcha.html

于是引入到 RuCaptcha 替换之前 ImageMagick 的方式。这回彻底完美了,不需要额外安装其它东西啦。

老用户升级注意

配置信息去掉了几个,注意处理,详见:CHANGELOG,使用方式不变。

使用

Gemfile

gem 'rucaptcha'

修改路由 config/routes.rb

Rails.application.routes.draw do
  mount RuCaptcha::Engine => "/rucaptcha"
end

在需要的 Controller 增加 verify_rucaptcha?

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

View 增加验证码:

<form>
  ...
  <div class="form-group">
    <%= rucaptcha_input_tag(class: 'form-control', placeholder: '输入验证码) %>
    <%= rucaptcha_image_tag(alt: '验证码,点击刷新') %>
  </div>
  ...
</form>

新的验证码效果

项目地址

https://github.com/huacnlee/rucaptcha

huacnlee 完美的 Ruby 图形验证码 Gem - RuCaptcha 提及了此话题。 01月22日 10:39

看起来不错!

Congratulations! My compliments to you.

很好,很强大

很实用,下次可以考虑将现在的验证码替换掉了。

正在用,赞一个~

@huacnlee 提了个 issue, 请跟进。

400 行代码就实现了这个功能 好棒好棒 不过我推断所有可能出现的验证码里面一定不会出现字母 e 和 g 因为代码里面有这么一行,没细看其他的逻辑 扩展的 C 代码里面

static const char *letters="abcdafahijklmnopqrstuvwxyz";

这是有意为之还是有何特殊的作用?

#10 楼 @helapu 因为哪个字体的 e g 容易看错

#10 楼 @helapu 核心那段 C 也不是我写的,我只是找到个好方案,适当封装了一下,便于使用

#12 楼 @huacnlee 我知道是使用的一个 C 实现 只是好奇

@huacnlee
在单元测试里面进行打桩的时候报没有找到 any_instance 这个方法。
rails 5.0.0
ruby 2.3.1
rucaptcha 2.0.0
请问这个如何解决?使用的是 minitest 的语法。

ERROR["test_create_user_via_posting_params_to_users", UsersControllerTest, 1.5036229289999028]
 test_create_user_via_posting_params_to_users#UsersControllerTest (1.50s)
NoMethodError:         NoMethodError: undefined method `any_instance' for ActionController::Base:Class
            test/controllers/users_controller_test.rb:132:in `block in <class:UsersControllerTest>'

Updated

测试了一下,这个问题和 Minitest 有关。 现在 minitest 没有 any_instance 这个方法,新的 minitest 通过一个扩展来提供 stub_any_instance 方法。https://github.com/codeodor/minitest-stub_any_instance

在使用上改成

test "create user via posting params to users" do
  # 绕过rucaptcha验证码判断
  ActionController::Base.stub_any_instance(:verify_rucaptcha?, true) do
    assert_difference 'User.count', 1 do
      post users_url, params: { user: { name: 'testnewuser', email: '[email protected]', password: '111111' } }
    end
  end
end

如此可以正常进行单元测试

#15 楼 @huacnlee 是的,已经找到一个别的方式来处理。使用 minitest 扩展可以解决单元测试问题。

klaus01 [该话题已被删除] 提及了此话题。 02月07日 17:18
huacnlee Rails 有比较好的验证码插件么? 提及了此话题。 02月14日 10:16

@huacnlee 请问一下,在使用 2.1.3 版本的情况下,验证码输错时的提示信息不显示,应该怎样使用?

我这边的情况是并没有使用 devise

@huacnlee 按说明配置好后,在 http://localhost:3000/rucaptcha/ 这里调试

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

我加入 gem 'dalli' 之后 bundle 验证码是能正常显示出来了,可是看到日志里有个错误:

Started GET "/rucaptcha/" for ::1 at 2017-04-30 12:21:25 +0800
Processing by RuCaptcha::CaptchaController#index as HTML
Dalli::Server#connect localhost:11211
localhost:11211 failed (count: 2) Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 11211
localhost:11211 is still down (for 9.548 seconds now)
  RuCaptcha   RuCaptcha sh: convert: command not found
  Rendering text template
  Rendered text template (0.0ms)
Sent data  (0.8ms)
Completed 200 OK in 16ms (Views: 0.6ms | ActiveRecord: 0.0ms)

貌似连接被拒绝?我看了 rubychina 的 gemfile,于是我又加了 gem 'kgio',然后错误如下:

Started GET "/rucaptcha/" for ::1 at 2017-04-30 12:32:17 +0800
Processing by RuCaptcha::CaptchaController#index as HTML
Dalli::Server#connect localhost:11211
localhost:11211 failed (count: 2) Errno::EINVAL: Invalid argument - setsockopt(2)
localhost:11211 is still down (for 5.050 seconds now)
  RuCaptcha   RuCaptcha sh: convert: command not found
  Rendering text template
  Rendered text template (0.0ms)
Sent data  (0.7ms)
Completed 200 OK in 26ms (Views: 0.5ms | ActiveRecord: 0.0ms)

这是我的 config/initializers/rucaptcha.rb:

RuCaptcha.configure do
  self.cache_store = [:mem_cache_store, '127.0.0.1']
end

我的 Gemfile:

gem 'devise'
gem 'rucaptcha', '>=2.1.3'
gem 'dalli'
gem 'kgio'

我配合 devise 来做验证,现在遇到的问题是,验证码图片是能正常显示的,但verify_rucaptcha?永远返回的是 false,即使验证码输对了也是 (如下图一图二)。看了服务器日志,所以怀疑是以上这个问题导致的。查了半天也没解决,这个是 cache 的问题吗?

我不知道需不需要加kgio这个 gem(看 rubychina 的 gemfile 写的),但如果不加gem 'dalli'的话验证码显示不出来。

图一

图二

更新(已解决)

看了下ChangeLog发现不需要手动配置了,默认用的是 file_store,于是我直接把 rucaptcha.rb 删了就正常了。

但是"file_store is still not a good way", 而手动配置 mem_cache_store 就会出现上面的错误,不知这是为什么呢

23 楼 已删除
24 楼 已删除

请问这个库支持纯数字的验证码吗?如果支持,应该如何实现呢?谢谢

======自问自答=========

看了 c 的那个库,貌似是写死了用 5 个英文字母

@huacnlee 这个 Gem 包能不能支持纯数字验证码,用了之后大家反馈字母识别度不高。

很好用~!

@huacnlee 能支持 html 而不是 .erb 吗?我看了 rubychina 是用了 rucaptcha_input_tag 和 rucaptcha_image_tag 这两个表单帮助方法实现的前端界面。

canonpd 展示一下自己的第一个 Rails 作品 - clwy.cn 提及了此话题。 03月22日 18:30

你好!请问验证码数字、字母没有刷新只有颜色改变是什么回事?

huacnlee 回复

我也想改成全部数字的验证码,看了里面 C 语言的代码,不知道怎么改,请教一下华顺,歇歇!

您好,verify_rucaptcha? 我的图片也一直返回 false,这个方法在哪里我想看看源码。 我打算利用它改写成 api 验证,目前 verify_rucaptcha? 一直 false, params[:_rucaptcha]

这是为什么啊

需要 登录 后方可回复, 如果你还没有账号请 注册新账号