2014-04-30 24 views
0

我有幾個模型需要生成唯一的令牌,以便我可以使用「祕密」URL訪問它們。現在,我這樣做,通過在每個模型創建一個「令牌」字段,並使用uuid模型的save方法填充,這樣的:爲模型快速生成唯一的靜態令牌

 self.token = uuid.uuid4().hex 
     while Notification.objects.filter(token=self.token).exists(): 
      self.token = uuid.uuid4().hex 

在這個作品中,明顯的缺點是:(1)I每個Notification條目需要有一個token字段,更重要的是,(2)每次創建新模型時,這至少會查詢一次數據庫。儘管uuid4()不太可能產生重複的令牌,但任何嚴重的應用程序仍然需要進行檢查。

是否有更好的方法可以讓我產生一個隨機的唯一令牌,或許可以從模型的ID派生,我可以保證是獨一無二的,但仍然是不可預測的/可猜測到攻擊,而無需進行查詢,以確保它是獨一無二的?

+0

我有同樣的問題,我在做同樣的事情,除了我使用'從django.utils導入加密,crypto.get_random_string(field_length)''。我看不出如何隨意創建一些東西,並且知道不經過檢查就不會重複。 – SColvin

回答

1

添加約束以確保令牌字段只接受唯一值。然後在保存方法中捕獲異常並重新生成令牌(如果有的話)。

unique=True在場上。

0

,你或許需要沿着itsdangerous線的東西,或者乾脆標準hmac

的想法是,你將建立你的服務器上的私有密鑰;你只需要做一次。

然後,使用該密鑰以及適當的散列算法來生成所謂的「消息認證代碼」,這是一種安全的方法,用於證明消息來自原始源,真的是來自您的情況,從你的服務器。該消息將包含您要訪問的數據的主鍵或其他有用的查詢值。

當響應其中一個請求時,您將消息分解爲查找值和簽名,並驗證該簽名是針對該特定值的。

一個缺點是主密鑰(或其他密鑰)以明文形式編碼在消息中;這可能會揭示更多關於對象的信息。也就是說,沒有(合理的)可能性,簽名可以被「猜到」任何特定的密鑰,沒有簽名密鑰。