宝石的想法:自动垃圾邮件保护与验证码中的before_filter当HTTP的方法是POST,PUT

2019-07-30 22:34发布

我正在考虑写一个自动垃圾邮件防护系统(也许我会写一个公共宝石)的轨道。

我的概念是包括在application_controller FE一个辅助方法:

class ApplicationController < ActionController::Base
  automatic_captcha_redirect(:min_time => 30.seconds :limit => 50)
...
end

然后,我想包括在自然而然每个控制器,它检查,如果当前请求是通过POST,PUT或删除,方法的before_filter。

如果用户的最后一个请求后小于:MIN_TIME,那么请求应该被重定向到一个验证码输入页面(张贴的用户数据保存在隐藏的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

如果用户提交了正确的验证码字,他的数据将被张贴到正确的行动。

你认为这就是变现? 任何批评或建议? 或一个想法如何实现这一行为呢?

编辑:

  • 这不应该通过所有ActiveRecord的堆栈; 不能将它可以称为中间件钩(导轨机架)执行?
    • 是的,将是一个好主意 - 但我不是很熟悉的轨道架:/
  • 什么文件上传? (你不能将它保存在一个隐藏的文件)
    • 嗯......也许,如果有在后一个文件的检查? (怎么可能实现呢?)
  • 什么关于Ajax发帖?
    • 也许发回HTTP状态码(FE 503服务暂时无法检索)
  • 为什么只有POST,而不是还PUT和DELETE?
    • 在我的问题纠正了这个

编辑:

处理的第一个结构(非机架式应用程序 - 我不知道怎么写架的应用程序):

0)设置在environment.rb中

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

1)用户数据发布

检查last_manipulation和最大值。 在application_controller.rb允许manipultations的量

class ApplicationController < ActionController::Base
  before_filter :automatic_captcha_redirect

  def automatic_captcha_redirect
    session[:last_manipulation_at][:manipultation] = [] unless session[:last_manipulation_at][:manipultation]
    # Checks if requests are falling under the specifications for showing captcha


    if !request.get? 
       && session[:last_manipulation_at][:date] > 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)... ... ...

最后一个)邮政用户数据到正确的位置

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

Answer 1:

其中一种方法可以放在一起:

  • 中间件/轨道,其监视请求和将信息添加到机架会话金属组分。

  • 控制器佣工的before_filters上可能需要验证码的东西

  • 用于显示验证码视图助手

你可以做的验证码速率通过传递的机制ARGS可调use

#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


Answer 2:

首先,我想说,这是一个功能非常好IDEEA。

我的QS /备注:

  • 这不应该通过所有ActiveRecord的堆栈; 不能将它可以称为中间件钩(导轨机架)执行?
  • 什么文件上传? (你不能将它保存在一个隐藏的文件)
  • 什么关于Ajax发帖?
  • 为什么只有POST,而不是还PUT和DELETE?

无论如何,我会更感兴趣的是看帖的去年5分钟数,例如,上一个请求的日期。 我相信这是更相关。



文章来源: Gem-idea: Automatic spam protection with captcha in before_filter when HTTP-method is post,put or delete