快速生成模型的唯一静态令牌
我有几个模型,我想为它们生成独特的令牌,这样我就可以通过一个“秘密”的网址来访问它们。目前,我是通过在每个模型上创建一个“令牌”字段,并在模型的 save
方法中使用 uuid
来填充这个字段,像这样:
self.token = uuid.uuid4().hex
while Notification.objects.filter(token=self.token).exists():
self.token = uuid.uuid4().hex
虽然这样做是可行的,但明显有几个缺点:(1) 我需要为每个 Notification
条目都有一个 token
字段,更重要的是,(2) 每次我创建一个新模型时,至少需要查询一次数据库。虽然 uuid4() 生成重复令牌的可能性非常小,但任何严肃的应用程序仍然需要进行检查。
有没有更好的方法可以生成一个随机的独特令牌?也许可以从模型的 ID 中派生出来,这样我可以确保它是独特的,但又不容易被攻击者预测或猜测,而且不需要查询来确保它的唯一性?
2 个回答
0
你可能想要使用类似于 itsdangerous 的东西,或者直接使用标准的 hmac 库。
这个想法是,你需要在服务器上建立一个私密的密钥;这一步只需要做一次。
然后,使用这个密钥和一个合适的哈希算法来生成一个叫做“消息认证码”的东西。这是一种安全的方法,可以证明消息确实是来自原始来源,也就是你的服务器。消息中会包含主键或者其他一些有用的查询值,用于访问你想要的数据。
当你回应一个请求时,你需要把消息拆分成查找值和签名,然后验证这个签名是否对应那个特定的值。
一个缺点是,主键(或者其他密钥)是以明文形式编码在消息中的;这可能会泄露比你想要的更多信息。不过,值得注意的是,没有签名密钥的情况下,几乎不可能“猜到”任何特定密钥的签名。
1
添加一个限制,确保这个令牌字段只能接受唯一的值。然后在保存的时候捕捉到这个异常,如果有重复的值,就重新生成一个令牌。
unique=True
是用在这个字段上的设置。