Gem-idea:当HTTP方法发布,放置或删除时,在before_filter中使用validation码自动保护垃圾邮件

我正在考虑为rails编写一个自动垃圾邮件保护系统(也许我会写一个公共gem)。

我的概念是在application_controller中包含一个辅助方法:

class ApplicationController  30.seconds :limit => 50) ... end 

然后我想在每个控制器中自动包含一个before_filter,如果当前请求是通过post,put或delete-method检查的话。

如果用户的上次发布请求小于:min_time,则应将请求重定向到captcha-input-page(发布的用户数据驻留在隐藏的html字段中)。

 # before_filter :check_spam def check_spam if !request.get? && session[:last_manipulation_at] && session[:last_manipulation_at] >= DateTime.now - 30.seconds redirect_to captcha_path # (doesn't know yet how to handle the post data to # display in hidden fields in the spam-captcha-form) end end 

在captcha.haml中

 =form_tag -request.params.each do |key, value| =hidden_field_tag key, value =captcha_image =submit_button_tag 

如果用户提交了正确的validation码,他的数据将被发布到正确的操作中。

你觉得那可以实现吗? 任何批评或建议? 或者想法如何实现这种行为?

编辑:

  • 这不应该通过所有的ActiveRecord堆栈; 它不能作为中间件钩子(Rails Rack)实现吗?
    • 是的,这是个好主意 – 但我对铁架不是很熟悉:/
  • 文件上传怎么样? (你不能将它存储在隐藏文件中)
    • 嗯…也许检查post中是否有文件? (怎么可能实现?)
  • 怎么样的Ajax发布?
    • 也许发送回http状态代码(fe 503 Service暂时不可用)
  • 为什么只有POST而不是PUT和DELETE?
    • 在我的问题中纠正了这一点

编辑:

第一个处理结构(作为非机架应用程序 – 我不知道如何编写机架应用程序):

0)environment.rb中的设置

 auto_recaptcha[:limit] = 10 auto_recaptcha[:min_time] = 1.minute 

1)用户发布数据

检查last_manipulation和max。 application_controller.rb中允许的操作量

 class ApplicationController  DateTime.now - auto_recaptcha[:min_time] && session[:last_manipulation_at][:manipultation].count < auto_recaptcha[:limit] # If user answered captcha, verify it if !verify_captcha(params) @url = request.url @params = request.params render "layouts/captcha.haml" else # Add successfull manipulation to counter session[:last_manipulation_at][:manipultation] << DateTime.now session[:last_manipulation_at][:date] = DateTime.now end end end end 

captcha.haml

 -form_tag @url do -request.params.each do |key, value| =hidden_field_tag key, value =captcha_image =submit_button_tag 

2)…… ……

last)将用户数据发布到正确的位置

 post(params) => users_path # path "/users" with method: post 

这可以放在一起的一种方式:

  • 中间件/ rails金属组件,用于监视请求并将信息添加到机架会话。

  • 有关可能需要validation码的事情的before_filters的控制器助手

  • 查看用于显示validation码的助手

您可以通过args传递use机制使validation码速率可调

 #config/environment.rb config.middleware.use 'CaptchaMiddleware',:period=>5.minutes,:limit=>50,:captcha_url=>'/captcha' 

此外,这不应该依赖于隐藏的表单字段,因为确定的机器人编写器可以只更改它们发布到服务器代码的值。

简单的中间件示例代码(稍微好于黑暗中的刺,但仍然)

 class CaptchaMiddleware def initialize app,options @app = app @options=options end def update_stats! #session based,on account of laziness session[:reqs] ||= [] session[:reqs].reject!{ |request| request < Time.now - @options[:period]} session[:reqs] << Time.now end def over_limit? session[:reqs].length > @options[:limit] end def call env @env = env if @env["REQUEST_METHOD"]!='GET' update_stats! if over_limit? return [302,{"Location: #{options[:captcha_url]}"},''] end end @app.call env end def session @env["rack.session"] end end 

首先,我想说这是一个非常好的function概念。

我的qs /备注:

  • 这不应该通过所有的ActiveRecord堆栈; 它不能作为中间件钩子(Rails Rack)实现吗?
  • 文件上传怎么样? (你不能将它存储在隐藏文件中)
  • 怎么样的Ajax发布?
  • 为什么只有POST而不是PUT和DELETE?

无论如何,我更感兴趣的是看到最后5分钟的post数量,例如,最后一次请求的日期。 我相信它更有意义。