2010-11-18 78 views
0

我有一個模型PhotoAlbum。Rails - 爲模型創建UID

我想讓Rails在創建PhotoAlbum時神奇地創建一個UID。最好是一個非常長的數字/字母數字UID,就好像一個壞人擁有這個UID一樣,他們可以做壞事。在

建議:

  • 使用什麼使UID
  • 哪裏來分配UID,我能做到這一點的模式作爲默認值?或者在模型中像之前一樣或者在創建之後?什麼是明智的方式來做到這一點?

感謝

回答

2

簡單的六角扳手怎麼樣?只需將僞隨機數據和模型數據組合在一起,並將其輸入到十六進制文件中即可獲得一個相當獨特的密鑰,一個簡單的檢查可以確保它非常獨特。

class Album 
    before_create :set_uid 

    protected 
    def set_uid 
     # This only works before_create obviously, otherwise it would 
     # find itself and loop eternally. 
     while self.uid.blank? or !Album.find_by_uid(self.uid).blank? 
     self.uid = Digest::SHA1.hexdigest("--#{self.title}--#{Time.current.usec}--") 
     end 
    end 
end 

你可能會清理一下,但它應該工作。

至於架構做,我猜這取決於你所使用的數據庫引擎,我不是專家那裏;)

+0

我不會使用它 - 但是然後我對安全性有些偏執。如果源代碼被公開發布,黑客可以通過少量測試來猜測任何對象的UID。他們可以簡單地在創建條目時嘗試每個使用組合。 – oskarpearson 2010-11-19 07:55:37

+0

或...如果有人直接複製並粘貼示例,攻擊者甚至不需要泄露源代碼,他們擁有您的代碼。假設他們擁有標題,並且由於Time.current.usec只返回一個999999的數字,他們只需要檢查999999個可能性,然後他們就擁有「祕密」 – oskarpearson 2010-11-19 08:03:22

+0

並且更有趣:讓我們假設這實際上是爲了合理大小的服務 - 創建數十萬個相冊。最終Time.current.usec將返回相同的數字。如果專輯的標題相同,並且usec值相同,則意味着兩個專輯的uid值將相同。如果原始海報創建一個通用的默認相冊名稱,或者人們使用「我的聚會」之類的東西作爲他們的相冊名稱,那麼這並不是很牽強。查看「生日悖論」並嘗試http://jeff.aaron.ca/cgi-bin/birthday – oskarpearson 2010-11-19 08:09:39

3

Rails的默認處理數據庫ID爲您服務。

雖然你真的不應該使用安全性 - 你應該使用插件來處理認證和授權,然後即使他們知道ID,壞人也不會做任何事情。

0

如何使用after_initialize鉤?

我正在假設你不希望UUID作爲你的主鍵(否則事情會更復雜)。我會爲了你的目的避免這種情況。

不幸的是,我正在做所有這些測試,所以我不能100%確定我沒有任何錯別字。如果您遇到任何問題,請隨時通知我。

首先,您需要將uuidtools添加到您的項目中。假設軌道2,這是到config/environment.rb

Rails::Initializer.run do |config| 
    .. 
    # You can try a later uuidtools version, but this is the one I've worked with 
    config.gem "uuidtools", :version => '2.1.1' 
    .. 
end 

一旦你添加了上面運行「命令耙寶石:安裝」,它應該下載並安裝寶石。

然後,在你的模型,添加以下代碼:

validates_length_of :uuid, :is => 36 # Untested.. makes sense to me though 
    def after_initialize 
    self.uuid ||= UUIDTools::UUID.random_create.to_s 
    end 

而在你的遷移創建表:

create table :photo_albums do |t| 
    .. 
    t.string :id, :limit => 36 
    .. 
end 

我希望幫助。

Oskar