如何保护我的网站免受多个帖子请求的影响?

时间:2015-05-16 13:39:59

标签: ruby-on-rails ruby

任何用户都可以喜欢'我网站上的照片。但是如果他多次按下按钮(例如10个),那么10个帖子请求将被发送到服务器。 我尝试在会话的帮助下解决。 我认为这段代码只需要每5秒钟一次。但它没有!有我的行动和before_filter:

def like
   photo.create_like if session[:voted].nil?
   session[:voted] = Time.now.to_a.first(3).reverse.join
   redirect_to root_path
end


def check_session
  a = Time.now.to_a.first(3).reverse.join
  b = a.to_i - session[:voted].to_i  
   session[:voted] = nil if b >= 5

end

3 个答案:

答案 0 :(得分:2)

您无法对会话执行此操作(至少不使用默认会话存储):默认情况下,rails会将会话存储在Cookie中。

Cookie是作为请求的一部分由浏览器发送的,服务器的响应可以选择更新它们。如果您快速连续几次单击“喜欢”按钮,那么您将触发多个请求,每个请求包含代表会话当前状态的cookie数据。您的响应会更新会话,但对于已经发送的请求来说已经太晚了 - 他们的会话数据已经发送到服务器并且不会包含响应所做的任何更改。

正如其他人所说,一个bandaid是使用Javascript来限制多次提交,但处理这个问题的唯一有效方法是在数据库级别(在likes表上使用唯一索引)。

答案 1 :(得分:1)

您在reverse方法中忘记了like,因此比较无效。它应该是:

session[:voted] = Time.now.to_a.first(3).reverse.join

同样在like您正在使用session[:voted]而在check_session中您正在使用session[:time]

虽然这也不会很好。最好使用Unix时间戳,让check_session返回一个布尔值。像这样:

def like
  photo.create_like if check_session
  session[:voted] = Time.now.to_i
  redirect_to root_path
end

def check_session
  session[:voted].blank? || (Time.now.to_i - session[:voted]) > 5
end

答案 2 :(得分:0)

禁用按钮 <%= submit_tag "Login", 'data-disable-with' => "Please wait.." %> 您可以在视图中添加条件以显示投票或想投票吗?如果用户已经投票