Rails更新属性安全性:使用回调或attr_accessible?

时间:2010-01-28 01:00:09

标签: ruby-on-rails security activerecord callback

我有一个网站模型,要求用户验证网站的所有权。

由于堆栈溢出,我能够在此处找到用户所有权验证的解决方案:Validate website ownership in rails

模型通过验证测试后,有一个已验证的属性设置为true。

我遇到的问题是当用户想要编辑他或她的网站的属性时,他或她可以在验证的属性保持为真时轻松更改域的名称,从而允许用户创建网站对象没有核实所有权。

我可以想出两种方法来解决这个问题: 1.如果网站的域名发生变化,请进行回调,将验证更改为false。 2.在创建新对象时允许域的attr_accessible,但在更新时不允许。

我很难实现如何实现其中任何一项。

3 个答案:

答案 0 :(得分:3)

回调和Active Record Dirty方法绝对是解决此类情况的方法。

before_update :set_domain_status

def set_domain_status
  self.verified = false if self.domain_changed?      
end

_changed?可以添加到任何属性,如果值已从最初从数据库加载的值更改,则返回true。

答案 1 :(得分:2)

我认为您的选项#1是最佳路线。否则,您将开始尝试协调创建和更新操作 - 您需要执行此操作来处理选项#2。

您可以覆盖域名的setter,然后执行自定义逻辑,如下所示:

在你的模特中:

def domain=(the_domain)
 raise ValidOwnerRequired if verified? && domain != the_domain
 # if we got here then the this record is new and this is a creation attempt
 @require_domain_verification = true 
 # do other stuff here..
end

def require_domain_verification?
  @require_domain_verification == true
end

然后有一个该模型的观察者:

def after_save(record)
  if record.require_domain_verification?
    SomeMailer.deliver_domain_verification(record)
  end
end

像这样......

答案 2 :(得分:0)

科迪,你的回答让我走上正轨。非常感谢!

这就是我在我的案例中所要求的:

  def domain=(the_domain)
     if domain != the_domain
     self[:domain] = the_domain
     self[:verified] = false
    end
  end

它运作得很好。