Rails 验证码解决方案和其他

手头有个需要,是关于做防爬虫表单提交的验证码问题,

于是,搜集了相关的资料,发现老的资料比较多。基本都是07年
比如:[url]http://babo.iteye.com/blog/72298[/url]
大部分的验证的办法,都是用Rmagick生成,这普通会有两个问题
1. Rmagick的内存问题
2. 每次验证都要生成

那么,现在的流行验证码解决方案怎么样了呢
于是,把自己东拼西凑的东西罗列一下:

[size=large]方案1[/size]. 首选的解决方案是把这个服务交给云服务提供商,这是流行趋势。如同,我们把反馈交给invoice。 recaptcha就专业提高验证码,第一流行的验证码插件就是利用recaptcha的。
这样优势会很明显使用起来非常简单,而且专业的提供商,效果也不错

大致使用如下:

 script/plugin install git://github.com/ambethia/recaptcha.git



设置API Keys


  recaptcha_tags :public_key => '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'

verify_recaptcha :private_key => '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'


也可以在environment.rb设置
  ENV['RECAPTCHA_PUBLIC_KEY']  = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
ENV['RECAPTCHA_PRIVATE_KEY'] = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'


View上加tag
recaptcha_tags
支持如下参数
[quote]:ssl: Uses secure http for captcha widget (default false)
:noscript: Include <noscript> content (default true)
:display: Takes a hash containing the theme and tabindex options per the API. (default nil)
:ajax: Render the dynamic AJAX captcha per the API. (default false)
:public_key: Your public API key, takes precedence over the ENV variable (default nil)
:error: Override the error code returned from the reCAPTCHA API (default nil)[/quote]


controller中验证如下:

  respond_to do |format|
if verify_recaptcha(:model => @post, :message => "Oh! It's error with reCAPTCHA!") && @post.save
# ...
else
# ...
end
end



[size=large]方案2:[/size] 先随机生成需要的验证码图片,用的时候直接验证
这样就解决了Rmagick的内存问题,而且,用户验证很快不用当时再生成图片。

使用如下:
依照如下安装Rmagick
[url]http://rmagick.rubyforge.org/install-faq.html[/url]
ubuntu如下:
[quote]
在linux下生成图片需要图片处理软件ImageMagick的Ruby语言RMagick库支持。安装RMagick最麻烦,我查了N多资料试了N次才安装成功。
1. 安装ImageMagick:sudo apt-get install imagemagick
2. 查看安装结果:dpkg -l | grep magick
3. 更新软件包列表:sudo apt-get update
4. 安装图片处理软件包libmagick9-dev:sudo apt-get install libmagick9-dev ruby1.8-dev
5. 安装接口软件包RMagick:sudo gem install rmagick
6. 说明:如果出现问题或者错误请执行下面命令:sudo apt-get remove --purge libmagick9-dev

在irb里require 'RMagick'。如果返回true,表示安装成功。
[/quote]

安装插件

script/plugin install git@github.com:zendesk/captcha.git


修改environment.rb

#environment.rb

CAPTCHA_SALT = 'Something really random here'



生成图片:
项目根目录,命令行执行
rake captcha:generate COUNT=250

可以带如下参数:

[quote]COUNT - the number of images to generate, default 3
IMAGE_HEIGHT - the height of the captcha image in pixels, default 50
IMAGE_WIDTH - the width of the captcha image in pixels, default 260
CAPTCHA_LENGTH - the number of characters in the captcha, default 5
FILE_FORMAT - the file type of the captcha image (png or gif)[/quote]


View显示:
验证码显示

<%= captcha_block %>


如果想更改验证码显示的样式可以参照captcha_helper.rb

Controller中验证如下:

PostController < ApplicationController

validates_captcha

def create
...
if captcha_validated?
...
else
...
end
end
end


其中的生成图片完全可以使用minimagick

[size=large]方案3.[/size] 不使用图片生成的验证方式

    script/plugin install http://code.subwindow.com/negative_captcha


Controller中添加回调
before_filter :setup_negative_captcha, :only => [:new, :create]


对应的执行方法如下:

    private
def setup_negative_captcha
@captcha = NegativeCaptcha.new(
:secret => NEGATIVE_CAPTCHA_SECRET, #A secret key entered in environment.rb. 'rake secret' will give you a good one.
:spinner => request.remote_ip,
:fields => [:name, :email, :body], #Whatever fields are in your form
:params => params)
end


验证逻辑部分

    def create
@comment = Comment.new(@captcha.values) #Decrypted params
if @captcha.valid? && @comment.save
redirect_to @comment
else
flash[:notice] = @captcha.error if @captcha.error
render :action => 'new'
end
end


View显示和表单如下:

    <% form_tag comments_path do -%>
<%= negative_captcha(@captcha) %>
<ul class="contact_us">
<li>
<label>Name:</label>
<%= negative_text_field_tag @captcha, :name %>
</li>
<li>
<label>Email:</label>
<%= negative_text_field_tag @captcha, :email %>
</li>
<li>
<label>Your Comment:</label>
<%= negative_text_area_tag @captcha, :body %>
</li>
<li>
<%= submit_tag %>
</li>
</ul>
<% end -%>



最后,单独就验证码的样式而言,完全可以使用minimagick或者,按照如下,改的更漂亮

require 'rubygems'
require 'RMagick'
class ProofImage
include Magick
attr_reader :text, :image
Jiggle = 15
Wobble = 15

def initialize(len=4)
chars = ('a'..'z').to_a # + ('0'..'9').to_a
text_array=[]
1.upto(len) {text_array << chars[rand(chars.length)]}
#background_type = "granite:" #花岗岩
#background_type = "netscape:" #彩条
#background_type = "xc:#EDF7E7" #指定背景色,例:xc:red
#background_type = "null:" #纯黑
granite = Magick::ImageList.new('null:')
canvas = Magick::ImageList.new
canvas.new_image(32*len, 50, Magick::TextureFill.new(granite))
gc = Magick::Draw.new
gc.font_family = 'times'
gc.pointsize = 40
cur = 10

text_array.each{|c|
rand(10) > 5 ? rot=rand(Wobble):rot= -rand(Wobble)
rand(10) > 5 ? weight = NormalWeight : weight = BoldWeight
gc.annotate(canvas,0,0,cur,30+rand(Jiggle),c){
self.rotation=rot
self.font_weight = weight
self.fill = 'green'
}
cur += 30
}
@text = text_array.to_s
@image = canvas.to_blob{
self.format="GIF"
}

#生成图片文件
#text.text(0, 0, " ")
#text.draw(canvas)
#canvas.write('test.gif') #图片位于项目根目录下。也可以使用linux中的绝对路径如:/home/chengang/test.gif

end
end
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值