延迟作业与自定义属性

3
我正在使用delayed job 3.0.2与ActiveRecord和Rails 3.2.3。我有一个用户模型,使用了has_secure_password mixin,因此密码仅以加密形式存储。现在我想使用delayed job发送欢迎电子邮件,其中应包含未加密的密码副本。
当创建记录时,明文密码位于User#password中。但是,延迟作业似乎仅序列化/反序列化记录的ID,并通过执行User.find(X)来创建模型的新实例。这样,我的明文密码就丢失了,并且用户在电子邮件中得到了空密码。
如何告诉delayed-job也对自定义“虚拟”属性进行序列化/反序列化,这些属性否则不会存储在数据库中?
这是我的delayed job 2.x的monkey patch,可以正常工作。
class ActiveRecord::Base
  def self.yaml_new(klass, tag, val)
    klass.find(val['attributes']['id']).tap do |m|
      val.except("attributes").each_pair{ |k, v| m.send("#{k}=", v) }
    end
  rescue ActiveRecord::RecordNotFound
    raise Delayed::DeserializationError
  end
end

它不能与delayed job 3.x一起使用。我也不是很想修复我的猴子补丁,因为我希望有一个正确的解决方案。


如果我理解你的帖子正确,你正在通过电子邮件发送明文密码。在我看来,通过电子邮件发送明文密码是一个安全问题。我不会包括它。这里有更多关于它的信息(https://dev59.com/JnNA5IYBdhLWcg3wKacx)的顶部答案。 - John
1个回答

2
在延迟工作3.x中,最好的方法是覆盖ActiveRecord类上的一些方法,然后强制Psych YAML反序列化器从序列化数据中加载ActiveRecord对象。默认情况下,延迟工作仅使用反序列化的id,然后从数据库中加载ActiveRecord对象。因此,假设我有一个名为ShipmentImport的ActiveRecord类,并且我想要一个名为'user_id'的attr_accessor与延迟工作的序列化/反序列化一起使用。这是我会做的事情。
在ShipmentImport ActiveRecord类中添加以下内容:
def encode_with(coder)
  super
  coder['user_id'] = @user_id
end

def init_with(coder)
 super
  @user_id = coder['user_id']
  self
end

在应用程序的初始化器中,为您的 ActiveRecord 类添加以下内容:
Psych.load_tags[['!ruby/ActiveRecord', ShipmentImport.name].join(':')] = ShipmentImport

谢谢,这很有帮助!您能解释一下初始化器代码在做什么吗?此外,您认为这可能是一个潜在的安全问题吗?也就是说,这可能会让外部人员更容易地发现属性的值吗? - CodeBiker
初始化代码告诉延迟作业通过实际反序列化序列化对象来初始化对象,而不仅仅是反序列化ID,然后从数据库中查找它。 - munchbit
此外,我并没有看到将延迟作业增强以支持非数据库字段属性的固有不安全性。应用这种技术的具体方式可能会引起安全问题,但几乎任何你编写的代码都是如此。 - munchbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接