Rails 验证码解决方案和其他

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

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

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

方案1. 首选的解决方案是把这个服务交给云服务提供商,这是流行趋势。如同,我们把反馈交给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
支持如下参数
引用
: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)



controller中验证如下:

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



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

使用如下:
依照如下安装Rmagick
http://rmagick.rubyforge.org/install-faq.html
ubuntu如下:
引用

在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,表示安装成功。


安装插件

script/plugin install [email protected]:zendesk/captcha.git


修改environment.rb

#environment.rb

   CAPTCHA_SALT = 'Something really random here'



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

可以带如下参数:

引用
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)



View显示:
验证码显示
  <%= captcha_block %>


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

Controller中验证如下:
PostController < ApplicationController

   validates_captcha

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


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

方案3. 不使用图片生成的验证方式

    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

你可能感兴趣的:(Ajax,linux,git,Ruby,Rails)