我有一個模型PhotoAlbum。Rails - 爲模型創建UID
我想讓Rails在創建PhotoAlbum時神奇地創建一個UID。最好是一個非常長的數字/字母數字UID,就好像一個壞人擁有這個UID一樣,他們可以做壞事。在
建議:
- 使用什麼使UID
- 哪裏來分配UID,我能做到這一點的模式作爲默認值?或者在模型中像之前一樣或者在創建之後?什麼是明智的方式來做到這一點?
感謝
我有一個模型PhotoAlbum。Rails - 爲模型創建UID
我想讓Rails在創建PhotoAlbum時神奇地創建一個UID。最好是一個非常長的數字/字母數字UID,就好像一個壞人擁有這個UID一樣,他們可以做壞事。在
建議:
感謝
簡單的六角扳手怎麼樣?只需將僞隨機數據和模型數據組合在一起,並將其輸入到十六進制文件中即可獲得一個相當獨特的密鑰,一個簡單的檢查可以確保它非常獨特。
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
你可能會清理一下,但它應該工作。
至於架構做,我猜這取決於你所使用的數據庫引擎,我不是專家那裏;)
Rails的默認處理數據庫ID爲您服務。
雖然你真的不應該使用安全性 - 你應該使用插件來處理認證和授權,然後即使他們知道ID,壞人也不會做任何事情。
如何使用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
我不會使用它 - 但是然後我對安全性有些偏執。如果源代碼被公開發布,黑客可以通過少量測試來猜測任何對象的UID。他們可以簡單地在創建條目時嘗試每個使用組合。 – oskarpearson 2010-11-19 07:55:37
或...如果有人直接複製並粘貼示例,攻擊者甚至不需要泄露源代碼,他們擁有您的代碼。假設他們擁有標題,並且由於Time.current.usec只返回一個999999的數字,他們只需要檢查999999個可能性,然後他們就擁有「祕密」 – oskarpearson 2010-11-19 08:03:22
並且更有趣:讓我們假設這實際上是爲了合理大小的服務 - 創建數十萬個相冊。最終Time.current.usec將返回相同的數字。如果專輯的標題相同,並且usec值相同,則意味着兩個專輯的uid值將相同。如果原始海報創建一個通用的默認相冊名稱,或者人們使用「我的聚會」之類的東西作爲他們的相冊名稱,那麼這並不是很牽強。查看「生日悖論」並嘗試http://jeff.aaron.ca/cgi-bin/birthday – oskarpearson 2010-11-19 08:09:39