2012-04-18 48 views
3

我使用ActiveRecord和Rails 3.2.3使用延遲作業3.0.2。我有一個使用has_secure_password mixin的用戶模型,所以密碼只能被加密存儲。現在我想使用延遲作業發送歡迎電子郵件,該電子郵件應包含未加密密碼的副本。使用自定義屬性延遲作業

創建記錄時,明文密碼在用戶密碼中。但是延遲工作似乎只是對記錄的id進行序列化/反序列化,並通過執行User.find(X)來創建模型的新實例。這樣我的純文本密碼就會丟失,用戶會在他的電子郵件中獲得一個空密碼。

我該如何告訴delayed-job序列化/反序列化自定義的「虛擬」屬性,否則它們不會存儲在數據庫中?

這是我的猴子補丁延遲工作2.x,它工作正常。

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 

它不適用於延遲作業3.x.我也沒有真正有興趣修復我的猴子補丁,因爲我希望適當的解決方案這個。

+0

如果我正確理解你的帖子,你通過電子郵件發送純文本密碼。在我看來,在電子郵件中發送純文本密碼是一個安全問題。我不會包括它。有關它在這裏頂部的答案更多信息(http://stackoverflow.com/questions/1069722/sending-username-and-password-through-email-after-user-registration-in-web-appli) – John 2012-08-02 07:04:10

回答

2

在延遲作業3.x中,最好的方法是覆蓋ActiveRecord類中的一些方法,然後強制Psych YAML反序列化器從序列化數據加載ActiveRecord對象。默認情況下,延遲作業僅使用反序列化的ID,然後從DB加載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 
+0

謝謝,這是非常有幫助的!你能解釋一下初始化器的代碼在做什麼嗎?另外,您是否可以將此視爲潛在的安全問題 - 也就是說,這可能會使外部人員更容易發現屬性的價值嗎? – CodeBiker 2013-07-03 04:40:23

+0

初始化代碼通過實際反序列化序列化對象來告訴延遲作業來初始化對象,而不僅僅是反序列化id,然後從數據庫中查找它。 – munchbit 2013-07-22 22:48:00

+0

此外,我還沒有發現任何內在的不安全因素,因爲增加了延遲作業以支持非數據庫字段的屬性。這種技術應用的具體方式可能會引發安全問題,但幾乎所有您編寫的代碼都是如此。 – munchbit 2013-07-22 23:03:15